diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index 4865516..085b76f 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -24,9 +24,11 @@
 #pragma once
 #include <nlohmann/json.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
-namespace messages {
+namespace messages
+{
 
 constexpr const char* messageVersionPrefix = "Base.1.2.0.";
 constexpr const char* messageAnnotation = "@Message.ExtendedInfo";
@@ -636,6 +638,6 @@
  * AUTOGENERATED FUNCTIONS END *
  *********************************/
 
-}  // namespace messages
+} // namespace messages
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
index 20d2951..8dbb0c2 100644
--- a/redfish-core/include/node.hpp
+++ b/redfish-core/include/node.hpp
@@ -18,161 +18,190 @@
 #include "privileges.hpp"
 #include "token_authorization_middleware.hpp"
 #include "webserver_common.hpp"
+
 #include "crow.h"
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * AsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class AsyncResp {
- public:
-  AsyncResp(crow::Response& response) : res(response) {}
+class AsyncResp
+{
+  public:
+    AsyncResp(crow::Response& response) : res(response)
+    {
+    }
 
-  ~AsyncResp() { res.end(); }
+    ~AsyncResp()
+    {
+        res.end();
+    }
 
-  crow::Response& res;
+    crow::Response& res;
 };
 
 /**
  * @brief  Abstract class used for implementing Redfish nodes.
  *
  */
-class Node {
- public:
-  template <typename... Params>
-  Node(CrowApp& app, std::string&& entityUrl, Params... params) {
-    app.routeDynamic(entityUrl.c_str())
-        .methods("GET"_method, "PATCH"_method, "POST"_method,
-                 "DELETE"_method)([&](const crow::Request& req,
-                                      crow::Response& res, Params... params) {
-          std::vector<std::string> paramVec = {params...};
-          dispatchRequest(app, req, res, paramVec);
-        });
-  }
-
-  virtual ~Node() = default;
-
-  const std::string* getUrl() const {
-    auto odataId = json.find("@odata.id");
-    if (odataId == json.end()) {
-      return nullptr;
+class Node
+{
+  public:
+    template <typename... Params>
+    Node(CrowApp& app, std::string&& entityUrl, Params... params)
+    {
+        app.routeDynamic(entityUrl.c_str())
+            .methods("GET"_method, "PATCH"_method, "POST"_method,
+                     "DELETE"_method)([&](const crow::Request& req,
+                                          crow::Response& res,
+                                          Params... params) {
+                std::vector<std::string> paramVec = {params...};
+                dispatchRequest(app, req, res, paramVec);
+            });
     }
 
-    return odataId->get_ptr<const std::string*>();
-  }
+    virtual ~Node() = default;
 
-  /**
-   * @brief Inserts subroute fields into for the node's json in the form:
-   *        "subroute_name" : { "odata.id": "node_url/subroute_name/" }
-   *        Excludes metadata urls starting with "$" and child urls having
-   *        more than one level.
-   *
-   * @return  None
-   */
-  void getSubRoutes(const std::vector<std::unique_ptr<Node>>& allNodes) {
-    const std::string* url = getUrl();
-    if (url == nullptr) {
-      // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
-      return;
+    const std::string* getUrl() const
+    {
+        auto odataId = json.find("@odata.id");
+        if (odataId == json.end())
+        {
+            return nullptr;
+        }
+
+        return odataId->get_ptr<const std::string*>();
     }
 
-    for (const auto& node : allNodes) {
-      const std::string* route = node->getUrl();
-      if (route == nullptr) {
-        // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
-        continue;
-      }
-      if (boost::starts_with(*route, *url)) {
-        std::string subRoute = route->substr(url->size());
-        if (subRoute.empty()) {
-          continue;
+    /**
+     * @brief Inserts subroute fields into for the node's json in the form:
+     *        "subroute_name" : { "odata.id": "node_url/subroute_name/" }
+     *        Excludes metadata urls starting with "$" and child urls having
+     *        more than one level.
+     *
+     * @return  None
+     */
+    void getSubRoutes(const std::vector<std::unique_ptr<Node>>& allNodes)
+    {
+        const std::string* url = getUrl();
+        if (url == nullptr)
+        {
+            // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
+            return;
         }
 
-        if (boost::starts_with(subRoute, "/")) {
-          subRoute.erase(0, 1);
+        for (const auto& node : allNodes)
+        {
+            const std::string* route = node->getUrl();
+            if (route == nullptr)
+            {
+                // BMCWEB_LOG_CRITICAL << "Unable to get url for route";
+                continue;
+            }
+            if (boost::starts_with(*route, *url))
+            {
+                std::string subRoute = route->substr(url->size());
+                if (subRoute.empty())
+                {
+                    continue;
+                }
+
+                if (boost::starts_with(subRoute, "/"))
+                {
+                    subRoute.erase(0, 1);
+                }
+
+                if (boost::ends_with(subRoute, "/"))
+                {
+                    subRoute.pop_back();
+                }
+
+                if (!boost::starts_with(subRoute, "$") &&
+                    subRoute.find('/') == std::string::npos)
+                {
+                    json[subRoute] = nlohmann::json{{"@odata.id", *route}};
+                }
+            }
         }
-
-        if (boost::ends_with(subRoute, "/")) {
-          subRoute.pop_back();
-        }
-
-        if (!boost::starts_with(subRoute, "$") &&
-            subRoute.find('/') == std::string::npos) {
-          json[subRoute] = nlohmann::json{{"@odata.id", *route}};
-        }
-      }
-    }
-  }
-
-  OperationMap entityPrivileges;
-
- protected:
-  // Node is designed to be an abstract class, so doGet is pure virtual
-  virtual void doGet(crow::Response& res, const crow::Request& req,
-                     const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doPatch(crow::Response& res, const crow::Request& req,
-                       const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doPost(crow::Response& res, const crow::Request& req,
-                      const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  virtual void doDelete(crow::Response& res, const crow::Request& req,
-                        const std::vector<std::string>& params) {
-    res.result(boost::beast::http::status::method_not_allowed);
-    res.end();
-  }
-
-  nlohmann::json json;
-
- private:
-  void dispatchRequest(CrowApp& app, const crow::Request& req,
-                       crow::Response& res,
-                       const std::vector<std::string>& params) {
-    auto ctx =
-        app.template getContext<crow::token_authorization::Middleware>(req);
-
-    if (!isMethodAllowedForUser(req.method(), entityPrivileges,
-                                ctx.session->username)) {
-      res.result(boost::beast::http::status::method_not_allowed);
-      res.end();
-      return;
     }
 
-    switch (req.method()) {
-      case "GET"_method:
-        doGet(res, req, params);
-        break;
+    OperationMap entityPrivileges;
 
-      case "PATCH"_method:
-        doPatch(res, req, params);
-        break;
-
-      case "POST"_method:
-        doPost(res, req, params);
-        break;
-
-      case "DELETE"_method:
-        doDelete(res, req, params);
-        break;
-
-      default:
-        res.result(boost::beast::http::status::not_found);
+  protected:
+    // Node is designed to be an abstract class, so doGet is pure virtual
+    virtual void doGet(crow::Response& res, const crow::Request& req,
+                       const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
         res.end();
     }
-    return;
-  }
+
+    virtual void doPatch(crow::Response& res, const crow::Request& req,
+                         const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    virtual void doPost(crow::Response& res, const crow::Request& req,
+                        const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    virtual void doDelete(crow::Response& res, const crow::Request& req,
+                          const std::vector<std::string>& params)
+    {
+        res.result(boost::beast::http::status::method_not_allowed);
+        res.end();
+    }
+
+    nlohmann::json json;
+
+  private:
+    void dispatchRequest(CrowApp& app, const crow::Request& req,
+                         crow::Response& res,
+                         const std::vector<std::string>& params)
+    {
+        auto ctx =
+            app.template getContext<crow::token_authorization::Middleware>(req);
+
+        if (!isMethodAllowedForUser(req.method(), entityPrivileges,
+                                    ctx.session->username))
+        {
+            res.result(boost::beast::http::status::method_not_allowed);
+            res.end();
+            return;
+        }
+
+        switch (req.method())
+        {
+            case "GET"_method:
+                doGet(res, req, params);
+                break;
+
+            case "PATCH"_method:
+                doPatch(res, req, params);
+                break;
+
+            case "POST"_method:
+                doPost(res, req, params);
+                break;
+
+            case "DELETE"_method:
+                doDelete(res, req, params);
+                break;
+
+            default:
+                res.result(boost::beast::http::status::not_found);
+                res.end();
+        }
+        return;
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
index 437bb15..0f6b903 100644
--- a/redfish-core/include/privileges.hpp
+++ b/redfish-core/include/privileges.hpp
@@ -16,15 +16,21 @@
 #pragma once
 
 #include <bitset>
-#include <cstdint>
-#include <vector>
-#include "crow.h"
 #include <boost/container/flat_map.hpp>
 #include <boost/optional.hpp>
+#include <cstdint>
+#include <vector>
 
-namespace redfish {
+#include "crow.h"
 
-enum class PrivilegeType { BASE, OEM };
+namespace redfish
+{
+
+enum class PrivilegeType
+{
+    BASE,
+    OEM
+};
 
 /** @brief A fixed array of compile time privileges  */
 constexpr std::array<const char*, 5> basePrivileges{
@@ -56,105 +62,118 @@
  *        (user domain) and false otherwise.
  *
  */
-class Privileges {
- public:
-  /**
-   * @brief Constructs object without any privileges active
-   *
-   */
-  Privileges() = default;
+class Privileges
+{
+  public:
+    /**
+     * @brief Constructs object without any privileges active
+     *
+     */
+    Privileges() = default;
 
-  /**
-   * @brief Constructs object with given privileges active
-   *
-   * @param[in] privilegeList  List of privileges to be activated
-   *
-   */
-  Privileges(std::initializer_list<const char*> privilegeList) {
-    for (const char* privilege : privilegeList) {
-      if (!setSinglePrivilege(privilege)) {
-        BMCWEB_LOG_CRITICAL << "Unable to set privilege " << privilege
-                            << "in constructor";
-      }
-    }
-  }
-
-  /**
-   * @brief Sets given privilege in the bitset
-   *
-   * @param[in] privilege  Privilege to be set
-   *
-   * @return               None
-   *
-   */
-  bool setSinglePrivilege(const char* privilege) {
-    for (int searchIndex = 0; searchIndex < privilegeNames.size();
-         searchIndex++) {
-      if (privilege == privilegeNames[searchIndex]) {
-        privilegeBitset.set(searchIndex);
-        return true;
-      }
+    /**
+     * @brief Constructs object with given privileges active
+     *
+     * @param[in] privilegeList  List of privileges to be activated
+     *
+     */
+    Privileges(std::initializer_list<const char*> privilegeList)
+    {
+        for (const char* privilege : privilegeList)
+        {
+            if (!setSinglePrivilege(privilege))
+            {
+                BMCWEB_LOG_CRITICAL << "Unable to set privilege " << privilege
+                                    << "in constructor";
+            }
+        }
     }
 
-    return false;
-  }
+    /**
+     * @brief Sets given privilege in the bitset
+     *
+     * @param[in] privilege  Privilege to be set
+     *
+     * @return               None
+     *
+     */
+    bool setSinglePrivilege(const char* privilege)
+    {
+        for (int searchIndex = 0; searchIndex < privilegeNames.size();
+             searchIndex++)
+        {
+            if (privilege == privilegeNames[searchIndex])
+            {
+                privilegeBitset.set(searchIndex);
+                return true;
+            }
+        }
 
-  /**
-   * @brief Sets given privilege in the bitset
-   *
-   * @param[in] privilege  Privilege to be set
-   *
-   * @return               None
-   *
-   */
-  bool setSinglePrivilege(const std::string& privilege) {
-    return setSinglePrivilege(privilege.c_str());
-  }
-
-  /**
-   * @brief Retrieves names of all active privileges for a given type
-   *
-   * @param[in] type    Base or OEM
-   *
-   * @return            Vector of active privileges.  Pointers are valid until
-   * the setSinglePrivilege is called, or the Privilege structure is destroyed
-   *
-   */
-  std::vector<const std::string*> getActivePrivilegeNames(
-      const PrivilegeType type) const {
-    std::vector<const std::string*> activePrivileges;
-
-    int searchIndex = 0;
-    int endIndex = basePrivilegeCount;
-    if (type == PrivilegeType::OEM) {
-      searchIndex = basePrivilegeCount - 1;
-      endIndex = privilegeNames.size();
+        return false;
     }
 
-    for (; searchIndex < endIndex; searchIndex++) {
-      if (privilegeBitset.test(searchIndex)) {
-        activePrivileges.emplace_back(&privilegeNames[searchIndex]);
-      }
+    /**
+     * @brief Sets given privilege in the bitset
+     *
+     * @param[in] privilege  Privilege to be set
+     *
+     * @return               None
+     *
+     */
+    bool setSinglePrivilege(const std::string& privilege)
+    {
+        return setSinglePrivilege(privilege.c_str());
     }
 
-    return activePrivileges;
-  }
+    /**
+     * @brief Retrieves names of all active privileges for a given type
+     *
+     * @param[in] type    Base or OEM
+     *
+     * @return            Vector of active privileges.  Pointers are valid until
+     * the setSinglePrivilege is called, or the Privilege structure is destroyed
+     *
+     */
+    std::vector<const std::string*>
+        getActivePrivilegeNames(const PrivilegeType type) const
+    {
+        std::vector<const std::string*> activePrivileges;
 
-  /**
-   * @brief Determines if this Privilege set is a superset of the given
-   * privilege set
-   *
-   * @param[in] privilege  Privilege to be checked
-   *
-   * @return               None
-   *
-   */
-  bool isSupersetOf(const Privileges& p) const {
-    return (privilegeBitset & p.privilegeBitset) == p.privilegeBitset;
-  }
+        int searchIndex = 0;
+        int endIndex = basePrivilegeCount;
+        if (type == PrivilegeType::OEM)
+        {
+            searchIndex = basePrivilegeCount - 1;
+            endIndex = privilegeNames.size();
+        }
 
- private:
-  std::bitset<maxPrivilegeCount> privilegeBitset = 0;
+        for (; searchIndex < endIndex; searchIndex++)
+        {
+            if (privilegeBitset.test(searchIndex))
+            {
+                activePrivileges.emplace_back(&privilegeNames[searchIndex]);
+            }
+        }
+
+        return activePrivileges;
+    }
+
+    /**
+     * @brief Determines if this Privilege set is a superset of the given
+     * privilege set
+     *
+     * @param[in] privilege  Privilege to be checked
+     *
+     * @return               None
+     *
+     */
+    bool isSupersetOf(const Privileges& p) const
+    {
+        return (privilegeBitset & p.privilegeBitset) == p.privilegeBitset;
+    }
+
+  private:
+    std::bitset<maxPrivilegeCount> privilegeBitset = 0;
 };
 
 using OperationMap = boost::container::flat_map<boost::beast::http::verb,
@@ -171,23 +190,28 @@
  */
 inline bool isMethodAllowedWithPrivileges(const boost::beast::http::verb method,
                                           const OperationMap& operationMap,
-                                          const Privileges& userPrivileges) {
-  const auto& it = operationMap.find(method);
-  if (it == operationMap.end()) {
-    return false;
-  }
-
-  // If there are no privileges assigned, assume no privileges required
-  if (it->second.empty()) {
-    return true;
-  }
-
-  for (auto& requiredPrivileges : it->second) {
-    if (userPrivileges.isSupersetOf(requiredPrivileges)) {
-      return true;
+                                          const Privileges& userPrivileges)
+{
+    const auto& it = operationMap.find(method);
+    if (it == operationMap.end())
+    {
+        return false;
     }
-  }
-  return false;
+
+    // If there are no privileges assigned, assume no privileges required
+    if (it->second.empty())
+    {
+        return true;
+    }
+
+    for (auto& requiredPrivileges : it->second)
+    {
+        if (userPrivileges.isSupersetOf(requiredPrivileges))
+        {
+            return true;
+        }
+    }
+    return false;
 }
 
 /**
@@ -201,13 +225,14 @@
  */
 inline bool isMethodAllowedForUser(const boost::beast::http::verb method,
                                    const OperationMap& operationMap,
-                                   const std::string& user) {
-  // TODO: load user privileges from configuration as soon as its available
-  // now we are granting all privileges to everyone.
-  Privileges userPrivileges{"Login", "ConfigureManager", "ConfigureSelf",
-                            "ConfigureUsers", "ConfigureComponents"};
+                                   const std::string& user)
+{
+    // TODO: load user privileges from configuration as soon as its available
+    // now we are granting all privileges to everyone.
+    Privileges userPrivileges{"Login", "ConfigureManager", "ConfigureSelf",
+                              "ConfigureUsers", "ConfigureComponents"};
 
-  return isMethodAllowedWithPrivileges(method, operationMap, userPrivileges);
+    return isMethodAllowedWithPrivileges(method, operationMap, userPrivileges);
 }
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index ab60abb..7f41b63 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -28,48 +28,53 @@
 #include "../lib/update_service.hpp"
 #include "webserver_common.hpp"
 
-namespace redfish {
+namespace redfish
+{
 /*
  * @brief Top level class installing and providing Redfish services
  */
-class RedfishService {
- public:
-  /*
-   * @brief Redfish service constructor
-   *
-   * Loads Redfish configuration and installs schema resources
-   *
-   * @param[in] app   Crow app on which Redfish will initialize
-   */
-  RedfishService(CrowApp& app) {
-    nodes.emplace_back(std::make_unique<AccountService>(app));
-    nodes.emplace_back(std::make_unique<SessionCollection>(app));
-    nodes.emplace_back(std::make_unique<Roles>(app));
-    nodes.emplace_back(std::make_unique<RoleCollection>(app));
-    nodes.emplace_back(std::make_unique<ServiceRoot>(app));
-    nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
-    nodes.emplace_back(std::make_unique<SessionService>(app));
-    nodes.emplace_back(std::make_unique<EthernetCollection>(app));
-    nodes.emplace_back(std::make_unique<EthernetInterface>(app));
-    nodes.emplace_back(std::make_unique<Thermal>(app));
-    nodes.emplace_back(std::make_unique<ManagerCollection>(app));
-    nodes.emplace_back(std::make_unique<Manager>(app));
-    nodes.emplace_back(std::make_unique<ChassisCollection>(app));
-    nodes.emplace_back(std::make_unique<Chassis>(app));
-    nodes.emplace_back(std::make_unique<UpdateService>(app));
-    nodes.emplace_back(std::make_unique<SoftwareInventoryCollection>(app));
-    nodes.emplace_back(std::make_unique<SoftwareInventory>(app));
-    nodes.emplace_back(std::make_unique<VlanNetworkInterfaceCollection>(app));
-    nodes.emplace_back(std::make_unique<SystemsCollection>(app));
-    nodes.emplace_back(std::make_unique<Systems>(app));
+class RedfishService
+{
+  public:
+    /*
+     * @brief Redfish service constructor
+     *
+     * Loads Redfish configuration and installs schema resources
+     *
+     * @param[in] app   Crow app on which Redfish will initialize
+     */
+    RedfishService(CrowApp& app)
+    {
+        nodes.emplace_back(std::make_unique<AccountService>(app));
+        nodes.emplace_back(std::make_unique<SessionCollection>(app));
+        nodes.emplace_back(std::make_unique<Roles>(app));
+        nodes.emplace_back(std::make_unique<RoleCollection>(app));
+        nodes.emplace_back(std::make_unique<ServiceRoot>(app));
+        nodes.emplace_back(std::make_unique<NetworkProtocol>(app));
+        nodes.emplace_back(std::make_unique<SessionService>(app));
+        nodes.emplace_back(std::make_unique<EthernetCollection>(app));
+        nodes.emplace_back(std::make_unique<EthernetInterface>(app));
+        nodes.emplace_back(std::make_unique<Thermal>(app));
+        nodes.emplace_back(std::make_unique<ManagerCollection>(app));
+        nodes.emplace_back(std::make_unique<Manager>(app));
+        nodes.emplace_back(std::make_unique<ChassisCollection>(app));
+        nodes.emplace_back(std::make_unique<Chassis>(app));
+        nodes.emplace_back(std::make_unique<UpdateService>(app));
+        nodes.emplace_back(std::make_unique<SoftwareInventoryCollection>(app));
+        nodes.emplace_back(std::make_unique<SoftwareInventory>(app));
+        nodes.emplace_back(
+            std::make_unique<VlanNetworkInterfaceCollection>(app));
+        nodes.emplace_back(std::make_unique<SystemsCollection>(app));
+        nodes.emplace_back(std::make_unique<Systems>(app));
 
-    for (auto& node : nodes) {
-      node->getSubRoutes(nodes);
+        for (auto& node : nodes)
+        {
+            node->getSubRoutes(nodes);
+        }
     }
-  }
 
- private:
-  std::vector<std::unique_ptr<Node>> nodes;
+  private:
+    std::vector<std::unique_ptr<Node>> nodes;
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index 25ac954..bde81ce 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -14,26 +14,36 @@
 // limitations under the License.
 */
 #pragma once
-#include <nlohmann/json.hpp>
 #include <crow/http_request.h>
 #include <crow/http_response.h>
 
-namespace redfish {
+#include <nlohmann/json.hpp>
 
-namespace json_util {
+namespace redfish
+{
+
+namespace json_util
+{
 
 /**
  * @brief Defines JSON utils operation status
  */
-enum class Result { SUCCESS, NOT_EXIST, WRONG_TYPE, NULL_POINTER };
+enum class Result
+{
+    SUCCESS,
+    NOT_EXIST,
+    WRONG_TYPE,
+    NULL_POINTER
+};
 
 /**
  * @brief Describes JSON utils messages requirement
  */
-enum class MessageSetting {
-  NONE = 0x0,       ///< No messages will be added
-  MISSING = 0x1,    ///< PropertyMissing message will be added
-  TYPE_ERROR = 0x2  ///< PropertyValueTypeError message will be added
+enum class MessageSetting
+{
+    NONE = 0x0,      ///< No messages will be added
+    MISSING = 0x1,   ///< PropertyMissing message will be added
+    TYPE_ERROR = 0x2 ///< PropertyValueTypeError message will be added
 };
 
 /**
@@ -287,6 +297,6 @@
 bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
                             nlohmann::json& reqJson);
 
-}  // namespace json_util
+} // namespace json_util
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 47b4c4c..c58cafd 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -17,40 +17,45 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class AccountService : public Node {
- public:
-  AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService";
-    Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#AccountService.AccountService";
-    Node::json["Id"] = "AccountService";
-    Node::json["Description"] = "BMC User Accounts";
-    Node::json["Name"] = "Account Service";
-    Node::json["ServiceEnabled"] = true;
-    Node::json["MinPasswordLength"] = 1;
-    Node::json["MaxPasswordLength"] = 20;
-    Node::json["Accounts"]["@odata.id"] = "/redfish/v1/AccountService/Accounts";
-    Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
+class AccountService : public Node
+{
+  public:
+    AccountService(CrowApp& app) : Node(app, "/redfish/v1/AccountService/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/AccountService";
+        Node::json["@odata.type"] = "#AccountService.v1_1_0.AccountService";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#AccountService.AccountService";
+        Node::json["Id"] = "AccountService";
+        Node::json["Description"] = "BMC User Accounts";
+        Node::json["Name"] = "Account Service";
+        Node::json["ServiceEnabled"] = true;
+        Node::json["MinPasswordLength"] = 1;
+        Node::json["MaxPasswordLength"] = 20;
+        Node::json["Accounts"]["@odata.id"] =
+            "/redfish/v1/AccountService/Accounts";
+        Node::json["Roles"]["@odata.id"] = "/redfish/v1/AccountService/Roles";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get,
-         {{"ConfigureUsers"}, {"ConfigureManager"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
-        {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get,
+             {{"ConfigureUsers"}, {"ConfigureManager"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::put, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureUsers"}}},
+            {boost::beast::http::verb::post, {{"ConfigureUsers"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index b1c20a5..7b68a27 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -16,9 +16,11 @@
 #pragma once
 
 #include "node.hpp"
+
 #include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * DBus types primitives for several generic DBus interfaces
@@ -47,220 +49,251 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandChassisProvider {
- public:
-  /**
-   * Function that retrieves all Chassis available through EntityManager.
-   * @param callback a function that shall be called to convert Dbus output into
-   * JSON.
-   */
-  template <typename CallbackFunc>
-  void getChassisList(CallbackFunc &&callback) {
-    const std::array<const char *, 4> interfaces = {
-        "xyz.openbmc_project.Inventory.Item.Board",
-        "xyz.openbmc_project.Inventory.Item.Chassis",
-        "xyz.openbmc_project.Inventory.Item.PowerSupply",
-        "xyz.openbmc_project.Inventory.Item.System",
+class OnDemandChassisProvider
+{
+  public:
+    /**
+     * Function that retrieves all Chassis available through EntityManager.
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON.
+     */
+    template <typename CallbackFunc>
+    void getChassisList(CallbackFunc &&callback)
+    {
+        const std::array<const char *, 4> interfaces = {
+            "xyz.openbmc_project.Inventory.Item.Board",
+            "xyz.openbmc_project.Inventory.Item.Chassis",
+            "xyz.openbmc_project.Inventory.Item.PowerSupply",
+            "xyz.openbmc_project.Inventory.Item.System",
+        };
+        crow::connections::systemBus->async_method_call(
+            [callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                const std::vector<std::string> &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // chassis list.
+                std::vector<std::string> chassisList;
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Entity Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, chassisList);
+                    return;
+                }
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::string &objpath : resp)
+                {
+                    std::size_t lastPos = objpath.rfind("/");
+                    if (lastPos != std::string::npos)
+                    {
+                        // and put it into output vector.
+                        chassisList.emplace_back(objpath.substr(lastPos + 1));
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, chassisList);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+            "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
     };
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](
-            const boost::system::error_code error_code,
-            const std::vector<std::string> &resp) {
-          // Callback requires vector<string> to retrieve all available chassis
-          // list.
-          std::vector<std::string> chassisList;
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Entity Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, chassisList);
-            return;
-          }
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::string &objpath : resp) {
-            std::size_t lastPos = objpath.rfind("/");
-            if (lastPos != std::string::npos) {
-              // and put it into output vector.
-              chassisList.emplace_back(objpath.substr(lastPos + 1));
-            }
-          }
-          // Finally make a callback with useful data
-          callback(true, chassisList);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-        "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
-  };
 };
 
 /**
  * ChassisCollection derived class for delivering Chassis Collection Schema
  */
-class ChassisCollection : public Node {
- public:
-  ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/") {
-    Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Chassis";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
-    Node::json["Name"] = "Chassis Collection";
+class ChassisCollection : public Node
+{
+  public:
+    ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
+    {
+        Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
+        Node::json["@odata.id"] = "/redfish/v1/Chassis";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
+        Node::json["Name"] = "Chassis Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
 
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // get chassis list, and call the below callback for JSON preparation
-    chassisProvider.getChassisList(
-        [&](const bool &success, const std::vector<std::string> &output) {
-          if (success) {
-            // ... prepare json array with appropriate @odata.id links
-            nlohmann::json chassisArray = nlohmann::json::array();
-            for (const std::string &chassisItem : output) {
-              chassisArray.push_back(
-                  {{"@odata.id", "/redfish/v1/Chassis/" + chassisItem}});
-            }
-            // Then attach members, count size and return,
-            Node::json["Members"] = chassisArray;
-            Node::json["Members@odata.count"] = chassisArray.size();
-            res.jsonValue = Node::json;
-          } else {
-            // ... otherwise, return INTERNALL ERROR
-            res.result(boost::beast::http::status::internal_server_error);
-          }
-          res.end();
-        });
-  }
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // get chassis list, and call the below callback for JSON preparation
+        chassisProvider.getChassisList(
+            [&](const bool &success, const std::vector<std::string> &output) {
+                if (success)
+                {
+                    // ... prepare json array with appropriate @odata.id links
+                    nlohmann::json chassisArray = nlohmann::json::array();
+                    for (const std::string &chassisItem : output)
+                    {
+                        chassisArray.push_back(
+                            {{"@odata.id",
+                              "/redfish/v1/Chassis/" + chassisItem}});
+                    }
+                    // Then attach members, count size and return,
+                    Node::json["Members"] = chassisArray;
+                    Node::json["Members@odata.count"] = chassisArray.size();
+                    res.jsonValue = Node::json;
+                }
+                else
+                {
+                    // ... otherwise, return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
 
-  // Chassis Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandChassisProvider chassisProvider;
+    // Chassis Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandChassisProvider chassisProvider;
 };
 
 /**
  * Chassis override class for delivering Chassis Schema
  */
-class Chassis : public Node {
- public:
-  Chassis(CrowApp &app)
-      : Node(app, "/redfish/v1/Chassis/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
-    Node::json["@odata.id"] = "/redfish/v1/Chassis";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
-    Node::json["Name"] = "Chassis Collection";
-    Node::json["ChassisType"] = "RackMount";
+class Chassis : public Node
+{
+  public:
+    Chassis(CrowApp &app) :
+        Node(app, "/redfish/v1/Chassis/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
+        Node::json["@odata.id"] = "/redfish/v1/Chassis";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
+        Node::json["Name"] = "Chassis Collection";
+        Node::json["ChassisType"] = "RackMount";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    res.jsonValue = Node::json;
-    const std::string &chassisId = params[0];
-    crow::connections::systemBus->async_method_call(
-        [&res, chassisId(std::string(chassisId)) ](
-            const boost::system::error_code error_code,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (error_code) {
-            res.jsonValue = {};
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
             res.result(boost::beast::http::status::internal_server_error);
             res.end();
             return;
-          }
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &object : subtree) {
-            const std::string &path = object.first;
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connectionNames = object.second;
+        }
 
-            if (!boost::ends_with(path, chassisId)) {
-              continue;
-            }
-            if (connectionNames.size() < 1) {
-              BMCWEB_LOG_ERROR << "Only got " << connectionNames.size()
-                               << " Connection names";
-              continue;
-            }
+        res.jsonValue = Node::json;
+        const std::string &chassisId = params[0];
+        crow::connections::systemBus->async_method_call(
+            [&res, chassisId(std::string(chassisId))](
+                const boost::system::error_code error_code,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (error_code)
+                {
+                    res.jsonValue = {};
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                    res.end();
+                    return;
+                }
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &object : subtree)
+                {
+                    const std::string &path = object.first;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connectionNames = object.second;
 
-            const std::string connectionName = connectionNames[0].first;
-            crow::connections::systemBus->async_method_call(
-                [&res, chassisId(std::string(chassisId)) ](
-                    const boost::system::error_code error_code,
-                    const std::vector<std::pair<std::string, VariantType>>
-                        &propertiesList) {
-                  for (const std::pair<std::string, VariantType> &property :
-                       propertiesList) {
-                    const std::string *value =
-                        mapbox::getPtr<const std::string>(property.second);
-                    if (value != nullptr) {
-                      res.jsonValue[property.first] = *value;
+                    if (!boost::ends_with(path, chassisId))
+                    {
+                        continue;
                     }
-                  }
-                  res.jsonValue["Name"] = chassisId;
-                  res.jsonValue["Id"] = chassisId;
-                  res.jsonValue["Thermal"] = {
-                      {"@odata.id",
-                       "/redfish/v1/Chassis/" + chassisId + "/Thermal"}};
-                  res.end();
-                },
-                connectionName, path, "org.freedesktop.DBus.Properties",
-                "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-            // Found the Connection we were looking for, return
-            return;
-          }
+                    if (connectionNames.size() < 1)
+                    {
+                        BMCWEB_LOG_ERROR << "Only got "
+                                         << connectionNames.size()
+                                         << " Connection names";
+                        continue;
+                    }
 
-          // Couldn't find an object with that name.  return an error
-          res.result(boost::beast::http::status::not_found);
+                    const std::string connectionName = connectionNames[0].first;
+                    crow::connections::systemBus->async_method_call(
+                        [&res, chassisId(std::string(chassisId))](
+                            const boost::system::error_code error_code,
+                            const std::vector<std::pair<
+                                std::string, VariantType>> &propertiesList) {
+                            for (const std::pair<std::string, VariantType>
+                                     &property : propertiesList)
+                            {
+                                const std::string *value =
+                                    mapbox::getPtr<const std::string>(
+                                        property.second);
+                                if (value != nullptr)
+                                {
+                                    res.jsonValue[property.first] = *value;
+                                }
+                            }
+                            res.jsonValue["Name"] = chassisId;
+                            res.jsonValue["Id"] = chassisId;
+                            res.jsonValue["Thermal"] = {
+                                {"@odata.id", "/redfish/v1/Chassis/" +
+                                                  chassisId + "/Thermal"}};
+                            res.end();
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "GetAll",
+                        "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    // Found the Connection we were looking for, return
+                    return;
+                }
 
-          res.end();
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/inventory", int32_t(0),
-        std::array<const char *, 1>{
-            "xyz.openbmc_project.Inventory.Decorator.Asset"});
-  }
+                // Couldn't find an object with that name.  return an error
+                res.result(boost::beast::http::status::not_found);
 
-  // Chassis Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandChassisProvider chassisProvider;
-};  // namespace redfish
+                res.end();
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/inventory", int32_t(0),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Inventory.Decorator.Asset"});
+    }
 
-}  // namespace redfish
+    // Chassis Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandChassisProvider chassisProvider;
+}; // namespace redfish
+
+} // namespace redfish
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 01111a4..0c64279 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -15,13 +15,14 @@
 */
 #pragma once
 
+#include <boost/container/flat_map.hpp>
 #include <dbus_singleton.hpp>
 #include <error_messages.hpp>
 #include <node.hpp>
 #include <utils/json_utils.hpp>
-#include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * DBus types primitives for several generic DBus interfaces
@@ -45,35 +46,40 @@
  * Structure for keeping IPv4 data required by Redfish
  * TODO(Pawel) consider change everything to ptr, or to non-ptr values.
  */
-struct IPv4AddressData {
-  std::string id;
-  const std::string *address;
-  const std::string *domain;
-  const std::string *gateway;
-  std::string netmask;
-  std::string origin;
-  bool global;
-  /**
-   * @brief Operator< to enable sorting
-   *
-   * @param[in] obj   Object to compare with
-   *
-   * @return This object id < supplied object id
-   */
-  bool operator<(const IPv4AddressData &obj) const { return (id < obj.id); }
+struct IPv4AddressData
+{
+    std::string id;
+    const std::string *address;
+    const std::string *domain;
+    const std::string *gateway;
+    std::string netmask;
+    std::string origin;
+    bool global;
+    /**
+     * @brief Operator< to enable sorting
+     *
+     * @param[in] obj   Object to compare with
+     *
+     * @return This object id < supplied object id
+     */
+    bool operator<(const IPv4AddressData &obj) const
+    {
+        return (id < obj.id);
+    }
 };
 
 /**
  * Structure for keeping basic single Ethernet Interface information
  * available from DBus
  */
-struct EthernetInterfaceData {
-  const unsigned int *speed;
-  const bool *autoNeg;
-  const std::string *hostname;
-  const std::string *defaultGateway;
-  const std::string *macAddress;
-  const unsigned int *vlanId;
+struct EthernetInterfaceData
+{
+    const unsigned int *speed;
+    const bool *autoNeg;
+    const std::string *hostname;
+    const std::string *defaultGateway;
+    const std::string *macAddress;
+    const unsigned int *vlanId;
 };
 
 /**
@@ -85,1264 +91,1493 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandEthernetProvider {
- private:
-  // Consts that may have influence on EthernetProvider performance/memory usage
-  const size_t maxIpV4AddressesPerInterface = 10;
+class OnDemandEthernetProvider
+{
+  private:
+    // Consts that may have influence on EthernetProvider performance/memory
+    // usage
+    const size_t maxIpV4AddressesPerInterface = 10;
 
-  // Helper function that allows to extract GetAllPropertiesType from
-  // GetManagedObjectsType, based on object path, and interface name
-  const PropertiesMapType *extractInterfaceProperties(
-      const sdbusplus::message::object_path &objpath,
-      const std::string &interface, const GetManagedObjectsType &dbus_data) {
-    const auto &dbusObj = dbus_data.find(objpath);
-    if (dbusObj != dbus_data.end()) {
-      const auto &iface = dbusObj->second.find(interface);
-      if (iface != dbusObj->second.end()) {
-        return &iface->second;
-      }
-    }
-    return nullptr;
-  }
-
-  // Helper Wrapper that does inline object_path conversion from string
-  // into sdbusplus::message::object_path type
-  inline const PropertiesMapType *extractInterfaceProperties(
-      const std::string &objpath, const std::string &interface,
-      const GetManagedObjectsType &dbus_data) {
-    const auto &dbusObj = sdbusplus::message::object_path{objpath};
-    return extractInterfaceProperties(dbusObj, interface, dbus_data);
-  }
-
-  // Helper function that allows to get pointer to the property from
-  // GetAllPropertiesType native, or extracted by GetAllPropertiesType
-  template <typename T>
-  inline T const *const extractProperty(const PropertiesMapType &properties,
-                                        const std::string &name) {
-    const auto &property = properties.find(name);
-    if (property != properties.end()) {
-      return mapbox::getPtr<const T>(property->second);
-    }
-    return nullptr;
-  }
-  // TODO(Pawel) Consider to move the above functions to dbus
-  // generic_interfaces.hpp
-
-  // Helper function that extracts data from several dbus objects and several
-  // interfaces required by single ethernet interface instance
-  void extractEthernetInterfaceData(const std::string &ethifaceId,
-                                    const GetManagedObjectsType &dbus_data,
-                                    EthernetInterfaceData &eth_data) {
-    // Extract data that contains MAC Address
-    const PropertiesMapType *macProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.MACAddress", dbus_data);
-
-    if (macProperties != nullptr) {
-      eth_data.macAddress =
-          extractProperty<std::string>(*macProperties, "MACAddress");
-    }
-
-    const PropertiesMapType *vlanProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.VLAN", dbus_data);
-
-    if (vlanProperties != nullptr) {
-      eth_data.vlanId = extractProperty<unsigned int>(*vlanProperties, "Id");
-    }
-
-    // Extract data that contains link information (auto negotiation and speed)
-    const PropertiesMapType *ethProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/" + ethifaceId,
-        "xyz.openbmc_project.Network.EthernetInterface", dbus_data);
-
-    if (ethProperties != nullptr) {
-      eth_data.autoNeg = extractProperty<bool>(*ethProperties, "AutoNeg");
-      eth_data.speed = extractProperty<unsigned int>(*ethProperties, "Speed");
-    }
-
-    // Extract data that contains network config (HostName and DefaultGW)
-    const PropertiesMapType *configProperties = extractInterfaceProperties(
-        "/xyz/openbmc_project/network/config",
-        "xyz.openbmc_project.Network.SystemConfiguration", dbus_data);
-
-    if (configProperties != nullptr) {
-      eth_data.hostname =
-          extractProperty<std::string>(*configProperties, "HostName");
-      eth_data.defaultGateway =
-          extractProperty<std::string>(*configProperties, "DefaultGateway");
-    }
-  }
-
-  // Helper function that changes bits netmask notation (i.e. /24)
-  // into full dot notation
-  inline std::string getNetmask(unsigned int bits) {
-    uint32_t value = 0xffffffff << (32 - bits);
-    std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
-                          std::to_string((value >> 16) & 0xff) + "." +
-                          std::to_string((value >> 8) & 0xff) + "." +
-                          std::to_string(value & 0xff);
-    return netmask;
-  }
-
-  // Helper function that extracts data for single ethernet ipv4 address
-  void extractIPv4Data(const std::string &ethifaceId,
-                       const GetManagedObjectsType &dbus_data,
-                       std::vector<IPv4AddressData> &ipv4_config) {
-    const std::string pathStart =
-        "/xyz/openbmc_project/network/" + ethifaceId + "/ipv4/";
-
-    // Since there might be several IPv4 configurations aligned with
-    // single ethernet interface, loop over all of them
-    for (auto &objpath : dbus_data) {
-      // Check if proper patter for object path appears
-      if (boost::starts_with(static_cast<const std::string &>(objpath.first),
-                             pathStart)) {
-        // and get approrpiate interface
-        const auto &interface =
-            objpath.second.find("xyz.openbmc_project.Network.IP");
-        if (interface != objpath.second.end()) {
-          // Make a properties 'shortcut', to make everything more readable
-          const PropertiesMapType &properties = interface->second;
-          // Instance IPv4AddressData structure, and set as appropriate
-          IPv4AddressData ipv4Address;
-
-          ipv4Address.id = static_cast<const std::string &>(objpath.first)
-                               .substr(pathStart.size());
-
-          // IPv4 address
-          ipv4Address.address =
-              extractProperty<std::string>(properties, "Address");
-          // IPv4 gateway
-          ipv4Address.gateway =
-              extractProperty<std::string>(properties, "Gateway");
-
-          // Origin is kind of DBus object so fetch pointer...
-          const std::string *origin =
-              extractProperty<std::string>(properties, "Origin");
-          if (origin != nullptr) {
-            ipv4Address.origin =
-                translateAddressOriginBetweenDBusAndRedfish(origin, true, true);
-          }
-
-          // Netmask is presented as PrefixLength
-          const auto *mask =
-              extractProperty<uint8_t>(properties, "PrefixLength");
-          if (mask != nullptr) {
-            // convert it to the string
-            ipv4Address.netmask = getNetmask(*mask);
-          }
-
-          // Attach IPv4 only if address is present
-          if (ipv4Address.address != nullptr) {
-            // Check if given address is local, or global
-            if (boost::starts_with(*ipv4Address.address, "169.254")) {
-              ipv4Address.global = false;
-            } else {
-              ipv4Address.global = true;
+    // Helper function that allows to extract GetAllPropertiesType from
+    // GetManagedObjectsType, based on object path, and interface name
+    const PropertiesMapType *extractInterfaceProperties(
+        const sdbusplus::message::object_path &objpath,
+        const std::string &interface, const GetManagedObjectsType &dbus_data)
+    {
+        const auto &dbusObj = dbus_data.find(objpath);
+        if (dbusObj != dbus_data.end())
+        {
+            const auto &iface = dbusObj->second.find(interface);
+            if (iface != dbusObj->second.end())
+            {
+                return &iface->second;
             }
-            ipv4_config.emplace_back(std::move(ipv4Address));
-          }
         }
-      }
+        return nullptr;
+    }
+
+    // Helper Wrapper that does inline object_path conversion from string
+    // into sdbusplus::message::object_path type
+    inline const PropertiesMapType *
+        extractInterfaceProperties(const std::string &objpath,
+                                   const std::string &interface,
+                                   const GetManagedObjectsType &dbus_data)
+    {
+        const auto &dbusObj = sdbusplus::message::object_path{objpath};
+        return extractInterfaceProperties(dbusObj, interface, dbus_data);
+    }
+
+    // Helper function that allows to get pointer to the property from
+    // GetAllPropertiesType native, or extracted by GetAllPropertiesType
+    template <typename T>
+    inline T const *const extractProperty(const PropertiesMapType &properties,
+                                          const std::string &name)
+    {
+        const auto &property = properties.find(name);
+        if (property != properties.end())
+        {
+            return mapbox::getPtr<const T>(property->second);
+        }
+        return nullptr;
+    }
+    // TODO(Pawel) Consider to move the above functions to dbus
+    // generic_interfaces.hpp
+
+    // Helper function that extracts data from several dbus objects and several
+    // interfaces required by single ethernet interface instance
+    void extractEthernetInterfaceData(const std::string &ethifaceId,
+                                      const GetManagedObjectsType &dbus_data,
+                                      EthernetInterfaceData &eth_data)
+    {
+        // Extract data that contains MAC Address
+        const PropertiesMapType *macProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.MACAddress", dbus_data);
+
+        if (macProperties != nullptr)
+        {
+            eth_data.macAddress =
+                extractProperty<std::string>(*macProperties, "MACAddress");
+        }
+
+        const PropertiesMapType *vlanProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.VLAN", dbus_data);
+
+        if (vlanProperties != nullptr)
+        {
+            eth_data.vlanId =
+                extractProperty<unsigned int>(*vlanProperties, "Id");
+        }
+
+        // Extract data that contains link information (auto negotiation and
+        // speed)
+        const PropertiesMapType *ethProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/" + ethifaceId,
+            "xyz.openbmc_project.Network.EthernetInterface", dbus_data);
+
+        if (ethProperties != nullptr)
+        {
+            eth_data.autoNeg = extractProperty<bool>(*ethProperties, "AutoNeg");
+            eth_data.speed =
+                extractProperty<unsigned int>(*ethProperties, "Speed");
+        }
+
+        // Extract data that contains network config (HostName and DefaultGW)
+        const PropertiesMapType *configProperties = extractInterfaceProperties(
+            "/xyz/openbmc_project/network/config",
+            "xyz.openbmc_project.Network.SystemConfiguration", dbus_data);
+
+        if (configProperties != nullptr)
+        {
+            eth_data.hostname =
+                extractProperty<std::string>(*configProperties, "HostName");
+            eth_data.defaultGateway = extractProperty<std::string>(
+                *configProperties, "DefaultGateway");
+        }
+    }
+
+    // Helper function that changes bits netmask notation (i.e. /24)
+    // into full dot notation
+    inline std::string getNetmask(unsigned int bits)
+    {
+        uint32_t value = 0xffffffff << (32 - bits);
+        std::string netmask = std::to_string((value >> 24) & 0xff) + "." +
+                              std::to_string((value >> 16) & 0xff) + "." +
+                              std::to_string((value >> 8) & 0xff) + "." +
+                              std::to_string(value & 0xff);
+        return netmask;
+    }
+
+    // Helper function that extracts data for single ethernet ipv4 address
+    void extractIPv4Data(const std::string &ethifaceId,
+                         const GetManagedObjectsType &dbus_data,
+                         std::vector<IPv4AddressData> &ipv4_config)
+    {
+        const std::string pathStart =
+            "/xyz/openbmc_project/network/" + ethifaceId + "/ipv4/";
+
+        // Since there might be several IPv4 configurations aligned with
+        // single ethernet interface, loop over all of them
+        for (auto &objpath : dbus_data)
+        {
+            // Check if proper patter for object path appears
+            if (boost::starts_with(
+                    static_cast<const std::string &>(objpath.first), pathStart))
+            {
+                // and get approrpiate interface
+                const auto &interface =
+                    objpath.second.find("xyz.openbmc_project.Network.IP");
+                if (interface != objpath.second.end())
+                {
+                    // Make a properties 'shortcut', to make everything more
+                    // readable
+                    const PropertiesMapType &properties = interface->second;
+                    // Instance IPv4AddressData structure, and set as
+                    // appropriate
+                    IPv4AddressData ipv4Address;
+
+                    ipv4Address.id =
+                        static_cast<const std::string &>(objpath.first)
+                            .substr(pathStart.size());
+
+                    // IPv4 address
+                    ipv4Address.address =
+                        extractProperty<std::string>(properties, "Address");
+                    // IPv4 gateway
+                    ipv4Address.gateway =
+                        extractProperty<std::string>(properties, "Gateway");
+
+                    // Origin is kind of DBus object so fetch pointer...
+                    const std::string *origin =
+                        extractProperty<std::string>(properties, "Origin");
+                    if (origin != nullptr)
+                    {
+                        ipv4Address.origin =
+                            translateAddressOriginBetweenDBusAndRedfish(
+                                origin, true, true);
+                    }
+
+                    // Netmask is presented as PrefixLength
+                    const auto *mask =
+                        extractProperty<uint8_t>(properties, "PrefixLength");
+                    if (mask != nullptr)
+                    {
+                        // convert it to the string
+                        ipv4Address.netmask = getNetmask(*mask);
+                    }
+
+                    // Attach IPv4 only if address is present
+                    if (ipv4Address.address != nullptr)
+                    {
+                        // Check if given address is local, or global
+                        if (boost::starts_with(*ipv4Address.address, "169.254"))
+                        {
+                            ipv4Address.global = false;
+                        }
+                        else
+                        {
+                            ipv4Address.global = true;
+                        }
+                        ipv4_config.emplace_back(std::move(ipv4Address));
+                    }
+                }
+            }
+        }
+
+        /**
+         * We have to sort this vector and ensure that order of IPv4 addresses
+         * is consistent between GETs to allow modification and deletion in
+         * PATCHes
+         */
+        std::sort(ipv4_config.begin(), ipv4_config.end());
+    }
+
+    static const constexpr int ipV4AddressSectionsCount = 4;
+
+  public:
+    /**
+     * @brief Creates VLAN for given interface with given Id through D-Bus
+     *
+     * @param[in] ifaceId       Id of interface for which VLAN will be created
+     * @param[in] inputVlanId   ID of the new VLAN
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void createVlan(const std::string &ifaceId, const uint64_t &inputVlanId,
+                    CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network",
+            "xyz.openbmc_project.Network.VLAN.Create", "VLAN", ifaceId,
+            static_cast<uint32_t>(inputVlanId));
+    };
+
+    /**
+     * @brief Sets given Id on the given VLAN interface through D-Bus
+     *
+     * @param[in] ifaceId       Id of VLAN interface that should be modified
+     * @param[in] inputVlanId   New ID of the VLAN
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    static void changeVlanId(const std::string &ifaceId,
+                             const uint32_t &inputVlanId,
+                             CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            std::string("/xyz/openbmc_project/network/") + ifaceId,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.VLAN", "Id",
+            sdbusplus::message::variant<uint32_t>(inputVlanId));
+    };
+
+    /**
+     * @brief Helper function that verifies IP address to check if it is in
+     *        proper format. If bits pointer is provided, also calculates active
+     *        bit count for Subnet Mask.
+     *
+     * @param[in]  ip     IP that will be verified
+     * @param[out] bits   Calculated mask in bits notation
+     *
+     * @return true in case of success, false otherwise
+     */
+    bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
+                                    uint8_t *bits = nullptr)
+    {
+        std::vector<std::string> bytesInMask;
+
+        boost::split(bytesInMask, ip, boost::is_any_of("."));
+
+        if (bytesInMask.size() != ipV4AddressSectionsCount)
+        {
+            return false;
+        }
+
+        if (bits != nullptr)
+        {
+            *bits = 0;
+        }
+
+        char *endPtr;
+        long previousValue = 255;
+        bool firstZeroInByteHit;
+        for (const std::string &byte : bytesInMask)
+        {
+            if (byte.empty())
+            {
+                return false;
+            }
+
+            // Use strtol instead of stroi to avoid exceptions
+            long value = std::strtol(byte.c_str(), &endPtr, 10);
+
+            // endPtr should point to the end of the string, otherwise given
+            // string is not 100% number
+            if (*endPtr != '\0')
+            {
+                return false;
+            }
+
+            // Value should be contained in byte
+            if (value < 0 || value > 255)
+            {
+                return false;
+            }
+
+            if (bits != nullptr)
+            {
+                // Mask has to be continuous between bytes
+                if (previousValue != 255 && value != 0)
+                {
+                    return false;
+                }
+
+                // Mask has to be continuous inside bytes
+                firstZeroInByteHit = false;
+
+                // Count bits
+                for (int bitIdx = 7; bitIdx >= 0; bitIdx--)
+                {
+                    if (value & (1 << bitIdx))
+                    {
+                        if (firstZeroInByteHit)
+                        {
+                            // Continuity not preserved
+                            return false;
+                        }
+                        else
+                        {
+                            (*bits)++;
+                        }
+                    }
+                    else
+                    {
+                        firstZeroInByteHit = true;
+                    }
+                }
+            }
+
+            previousValue = value;
+        }
+
+        return true;
     }
 
     /**
-     * We have to sort this vector and ensure that order of IPv4 addresses
-     * is consistent between GETs to allow modification and deletion in PATCHes
+     * @brief Changes IPv4 address type property (Address, Gateway)
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be modified
+     * @param[in] ipIdx       index of IP in input array that should be modified
+     * @param[in] ipHash      DBus Hash id of modified IP
+     * @param[in] name        Name of field in JSON representation
+     * @param[in] newValue    New value that should be written
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return true if give IP is valid and has been sent do D-Bus, false
+     * otherwise
      */
-    std::sort(ipv4_config.begin(), ipv4_config.end());
-  }
-
-  static const constexpr int ipV4AddressSectionsCount = 4;
-
- public:
-  /**
-   * @brief Creates VLAN for given interface with given Id through D-Bus
-   *
-   * @param[in] ifaceId       Id of interface for which VLAN will be created
-   * @param[in] inputVlanId   ID of the new VLAN
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void createVlan(const std::string &ifaceId, const uint64_t &inputVlanId,
-                  CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "xyz.openbmc_project.Network.VLAN.Create", "VLAN", ifaceId,
-        static_cast<uint32_t>(inputVlanId));
-  };
-
-  /**
-   * @brief Sets given Id on the given VLAN interface through D-Bus
-   *
-   * @param[in] ifaceId       Id of VLAN interface that should be modified
-   * @param[in] inputVlanId   New ID of the VLAN
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  static void changeVlanId(const std::string &ifaceId,
-                           const uint32_t &inputVlanId,
-                           CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        std::string("/xyz/openbmc_project/network/") + ifaceId,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.VLAN", "Id",
-        sdbusplus::message::variant<uint32_t>(inputVlanId));
-  };
-
-  /**
-   * @brief Helper function that verifies IP address to check if it is in
-   *        proper format. If bits pointer is provided, also calculates active
-   *        bit count for Subnet Mask.
-   *
-   * @param[in]  ip     IP that will be verified
-   * @param[out] bits   Calculated mask in bits notation
-   *
-   * @return true in case of success, false otherwise
-   */
-  bool ipv4VerifyIpAndGetBitcount(const std::string &ip,
-                                  uint8_t *bits = nullptr) {
-    std::vector<std::string> bytesInMask;
-
-    boost::split(bytesInMask, ip, boost::is_any_of("."));
-
-    if (bytesInMask.size() != ipV4AddressSectionsCount) {
-      return false;
-    }
-
-    if (bits != nullptr) {
-      *bits = 0;
-    }
-
-    char *endPtr;
-    long previousValue = 255;
-    bool firstZeroInByteHit;
-    for (const std::string &byte : bytesInMask) {
-      if (byte.empty()) {
-        return false;
-      }
-
-      // Use strtol instead of stroi to avoid exceptions
-      long value = std::strtol(byte.c_str(), &endPtr, 10);
-
-      // endPtr should point to the end of the string, otherwise given string
-      // is not 100% number
-      if (*endPtr != '\0') {
-        return false;
-      }
-
-      // Value should be contained in byte
-      if (value < 0 || value > 255) {
-        return false;
-      }
-
-      if (bits != nullptr) {
-        // Mask has to be continuous between bytes
-        if (previousValue != 255 && value != 0) {
-          return false;
-        }
-
-        // Mask has to be continuous inside bytes
-        firstZeroInByteHit = false;
-
-        // Count bits
-        for (int bitIdx = 7; bitIdx >= 0; bitIdx--) {
-          if (value & (1 << bitIdx)) {
-            if (firstZeroInByteHit) {
-              // Continuity not preserved
-              return false;
-            } else {
-              (*bits)++;
+    void changeIPv4AddressProperty(const std::string &ifaceId, int ipIdx,
+                                   const std::string &ipHash,
+                                   const std::string &name,
+                                   const std::string &newValue,
+                                   const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         name{std::move(name)}, newValue{std::move(newValue)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
             }
-          } else {
-            firstZeroInByteHit = true;
-          }
-        }
-      }
-
-      previousValue = value;
-    }
-
-    return true;
-  }
-
-  /**
-   * @brief Changes IPv4 address type property (Address, Gateway)
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be modified
-   * @param[in] ipIdx       index of IP in input array that should be modified
-   * @param[in] ipHash      DBus Hash id of modified IP
-   * @param[in] name        Name of field in JSON representation
-   * @param[in] newValue    New value that should be written
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return true if give IP is valid and has been sent do D-Bus, false
-   * otherwise
-   */
-  void changeIPv4AddressProperty(const std::string &ifaceId, int ipIdx,
-                                 const std::string &ipHash,
-                                 const std::string &name,
-                                 const std::string &newValue,
-                                 const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback = [
-      asyncResp, ipIdx{std::move(ipIdx)}, name{std::move(name)},
-      newValue{std::move(newValue)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/" + name);
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] = newValue;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", name,
-        sdbusplus::message::variant<std::string>(newValue));
-  };
-
-  /**
-   * @brief Changes IPv4 address origin property
-   *
-   * @param[in] ifaceId       Id of interface whose IP should be modified
-   * @param[in] ipIdx         index of IP in input array that should be modified
-   * @param[in] ipHash        DBus Hash id of modified IP
-   * @param[in] newValue      New value in Redfish format
-   * @param[in] newValueDbus  New value in D-Bus format
-   * @param[io] asyncResp     Response object that will be returned to client
-   *
-   * @return true if give IP is valid and has been sent do D-Bus, false
-   * otherwise
-   */
-  void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
-                        const std::string &ipHash, const std::string &newValue,
-                        const std::string &newValueDbus,
-                        const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback =
-        [ asyncResp, ipIdx{std::move(ipIdx)},
-          newValue{std::move(newValue)} ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/AddressOrigin");
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
-            newValue;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", "Origin",
-        sdbusplus::message::variant<std::string>(newValueDbus));
-  };
-
-  /**
-   * @brief Modifies SubnetMask for given IP
-   *
-   * @param[in] ifaceId      Id of interface whose IP should be modified
-   * @param[in] ipIdx        index of IP in input array that should be modified
-   * @param[in] ipHash       DBus Hash id of modified IP
-   * @param[in] newValueStr  Mask in dot notation as string
-   * @param[in] newValue     Mask as PrefixLength in bitcount
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void changeIPv4SubnetMaskProperty(
-      const std::string &ifaceId, int ipIdx, const std::string &ipHash,
-      const std::string &newValueStr, uint8_t &newValue,
-      const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto callback = [
-      asyncResp, ipIdx{std::move(ipIdx)}, newValueStr{std::move(newValueStr)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
-      } else {
-        asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
-            newValueStr;
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(callback), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.IP", "PrefixLength",
-        sdbusplus::message::variant<uint8_t>(newValue));
-  };
-
-  /**
-   * @brief Disables VLAN with given ifaceId
-   *
-   * @param[in] ifaceId   Id of VLAN interface that should be disabled
-   * @param[in] callback  Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        std::string("/xyz/openbmc_project/network/") + ifaceId,
-        "xyz.openbmc_project.Object.Delete", "Delete");
-  };
-
-  /**
-   * @brief Sets given HostName of the machine through D-Bus
-   *
-   * @param[in] newHostname   New name that HostName will be changed to
-   * @param[in] callback      Function that will be called after the operation
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void setHostName(const std::string &newHostname, CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        callback, "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/config",
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
-        sdbusplus::message::variant<std::string>(newHostname));
-  };
-
-  /**
-   * @brief Deletes given IPv4
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be deleted
-   * @param[in] ipIdx       index of IP in input array that should be deleted
-   * @param[in] ipHash      DBus Hash id of IP that should be deleted
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
-                  unsigned int ipIdx,
-                  const std::shared_ptr<AsyncResp> &asyncResp) {
-    crow::connections::systemBus->async_method_call(
-        [ ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)} ](
-            const boost::system::error_code ec) {
-          if (ec) {
-            messages::addMessageToJson(
-                asyncResp->res.jsonValue, messages::internalError(),
-                "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
-          } else {
-            asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
-          }
-        },
-        "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
-        "xyz.openbmc_project.Object.Delete", "Delete");
-  }
-
-  /**
-   * @brief Creates IPv4 with given data
-   *
-   * @param[in] ifaceId     Id of interface whose IP should be deleted
-   * @param[in] ipIdx       index of IP in input array that should be deleted
-   * @param[in] ipHash      DBus Hash id of IP that should be deleted
-   * @param[io] asyncResp   Response object that will be returned to client
-   *
-   * @return None
-   */
-  void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
-                  uint8_t subnetMask, const std::string &gateway,
-                  const std::string &address,
-                  const std::shared_ptr<AsyncResp> &asyncResp) {
-    auto createIpHandler = [
-      ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)}
-    ](const boost::system::error_code ec) {
-      if (ec) {
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue, messages::internalError(),
-            "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
-      }
-    };
-
-    crow::connections::systemBus->async_method_call(
-        std::move(createIpHandler), "xyz.openbmc_project.Network",
-        "/xyz/openbmc_project/network/" + ifaceId,
-        "xyz.openbmc_project.Network.IP.Create", "IP",
-        "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
-        gateway);
-  }
-
-  /**
-   * @brief Translates Address Origin value from D-Bus to Redfish format and
-   *        vice-versa
-   *
-   * @param[in] inputOrigin Input value that should be translated
-   * @param[in] isIPv4      True for IPv4 origins, False for IPv6
-   * @param[in] isFromDBus  True for DBus->Redfish conversion, false for reverse
-   *
-   * @return Empty string in case of failure, translated value otherwise
-   */
-  std::string translateAddressOriginBetweenDBusAndRedfish(
-      const std::string *inputOrigin, bool isIPv4, bool isFromDBus) {
-    // Invalid pointer
-    if (inputOrigin == nullptr) {
-      return "";
-    }
-
-    static const constexpr unsigned int firstIPv4OnlyIdx = 1;
-    static const constexpr unsigned int firstIPv6OnlyIdx = 3;
-
-    std::array<std::pair<const char *, const char *>, 6> translationTable{
-        {{"xyz.openbmc_project.Network.IP.AddressOrigin.Static", "Static"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCP"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-          "IPv4LinkLocal"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCPv6"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
-          "LinkLocal"},
-         {"xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC", "SLAAC"}}};
-
-    for (unsigned int i = 0; i < translationTable.size(); i++) {
-      // Skip unrelated
-      if (isIPv4 && i >= firstIPv6OnlyIdx) break;
-      if (!isIPv4 && i >= firstIPv4OnlyIdx && i < firstIPv6OnlyIdx) continue;
-
-      // When translating D-Bus to Redfish compare input to first element
-      if (isFromDBus && translationTable[i].first == *inputOrigin)
-        return translationTable[i].second;
-
-      // When translating Redfish to D-Bus compare input to second element
-      if (!isFromDBus && translationTable[i].second == *inputOrigin)
-        return translationTable[i].first;
-    }
-
-    // If we are still here, that means that value has not been found
-    return "";
-  }
-
-  /**
-   * Function that retrieves all properties for given Ethernet Interface
-   * Object
-   * from EntityManager Network Manager
-   * @param ethifaceId a eth interface id to query on DBus
-   * @param callback a function that shall be called to convert Dbus output
-   * into JSON
-   */
-  template <typename CallbackFunc>
-  void getEthernetIfaceData(const std::string &ethifaceId,
-                            CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        [
-          this, ethifaceId{std::move(ethifaceId)}, callback{std::move(callback)}
-        ](const boost::system::error_code error_code,
-          const GetManagedObjectsType &resp) {
-          EthernetInterfaceData ethData{};
-          std::vector<IPv4AddressData> ipv4Data;
-          ipv4Data.reserve(maxIpV4AddressesPerInterface);
-
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at
-            // this moment, just return success=false, and empty output. Since
-            // size of vector may vary depending on information from Network
-            // Manager, and empty output could not be treated same way as
-            // error.
-            callback(false, ethData, ipv4Data);
-            return;
-          }
-
-          // Find interface
-          if (resp.find("/xyz/openbmc_project/network/" + ethifaceId) ==
-              resp.end()) {
-            // Interface has not been found
-            callback(false, ethData, ipv4Data);
-            return;
-          }
-
-          extractEthernetInterfaceData(ethifaceId, resp, ethData);
-          extractIPv4Data(ethifaceId, resp, ipv4Data);
-
-          // Fix global GW
-          for (IPv4AddressData &ipv4 : ipv4Data) {
-            if ((ipv4.global) &&
-                ((ipv4.gateway == nullptr) || (*ipv4.gateway == "0.0.0.0"))) {
-              ipv4.gateway = ethData.defaultGateway;
+            else
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx][name] =
+                    newValue;
             }
-          }
+        };
 
-          // Finally make a callback with useful data
-          callback(true, ethData, ipv4Data);
-        },
-        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  };
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", name,
+            sdbusplus::message::variant<std::string>(newValue));
+    };
 
-  /**
-   * Function that retrieves all Ethernet Interfaces available through Network
-   * Manager
-   * @param callback a function that shall be called to convert Dbus output into
-   * JSON.
-   */
-  template <typename CallbackFunc>
-  void getEthernetIfaceList(CallbackFunc &&callback) {
-    crow::connections::systemBus->async_method_call(
-        [ this, callback{std::move(callback)} ](
-            const boost::system::error_code error_code,
-            GetManagedObjectsType &resp) {
-          // Callback requires vector<string> to retrieve all available ethernet
-          // interfaces
-          std::vector<std::string> ifaceList;
-          ifaceList.reserve(resp.size());
-          if (error_code) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Network Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, ifaceList);
-            return;
-          }
+    /**
+     * @brief Changes IPv4 address origin property
+     *
+     * @param[in] ifaceId       Id of interface whose IP should be modified
+     * @param[in] ipIdx         index of IP in input array that should be
+     * modified
+     * @param[in] ipHash        DBus Hash id of modified IP
+     * @param[in] newValue      New value in Redfish format
+     * @param[in] newValueDbus  New value in D-Bus format
+     * @param[io] asyncResp     Response object that will be returned to client
+     *
+     * @return true if give IP is valid and has been sent do D-Bus, false
+     * otherwise
+     */
+    void changeIPv4Origin(const std::string &ifaceId, int ipIdx,
+                          const std::string &ipHash,
+                          const std::string &newValue,
+                          const std::string &newValueDbus,
+                          const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         newValue{std::move(newValue)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) +
+                        "/AddressOrigin");
+            }
+            else
+            {
+                asyncResp->res
+                    .jsonValue["IPv4Addresses"][ipIdx]["AddressOrigin"] =
+                    newValue;
+            }
+        };
 
-          // Iterate over all retrieved ObjectPaths.
-          for (auto &objpath : resp) {
-            // And all interfaces available for certain ObjectPath.
-            for (auto &interface : objpath.second) {
-              // If interface is xyz.openbmc_project.Network.EthernetInterface,
-              // this is what we're looking for.
-              if (interface.first ==
-                  "xyz.openbmc_project.Network.EthernetInterface") {
-                // Cut out everything until last "/", ...
-                const std::string &ifaceId =
-                    static_cast<const std::string &>(objpath.first);
-                std::size_t lastPos = ifaceId.rfind("/");
-                if (lastPos != std::string::npos) {
-                  // and put it into output vector.
-                  ifaceList.emplace_back(ifaceId.substr(lastPos + 1));
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", "Origin",
+            sdbusplus::message::variant<std::string>(newValueDbus));
+    };
+
+    /**
+     * @brief Modifies SubnetMask for given IP
+     *
+     * @param[in] ifaceId      Id of interface whose IP should be modified
+     * @param[in] ipIdx        index of IP in input array that should be
+     * modified
+     * @param[in] ipHash       DBus Hash id of modified IP
+     * @param[in] newValueStr  Mask in dot notation as string
+     * @param[in] newValue     Mask as PrefixLength in bitcount
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void changeIPv4SubnetMaskProperty(
+        const std::string &ifaceId, int ipIdx, const std::string &ipHash,
+        const std::string &newValueStr, uint8_t &newValue,
+        const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto callback = [asyncResp, ipIdx{std::move(ipIdx)},
+                         newValueStr{std::move(newValueStr)}](
+                            const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/SubnetMask");
+            }
+            else
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][ipIdx]["SubnetMask"] =
+                    newValueStr;
+            }
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(callback), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.IP", "PrefixLength",
+            sdbusplus::message::variant<uint8_t>(newValue));
+    };
+
+    /**
+     * @brief Disables VLAN with given ifaceId
+     *
+     * @param[in] ifaceId   Id of VLAN interface that should be disabled
+     * @param[in] callback  Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    static void disableVlan(const std::string &ifaceId, CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            std::string("/xyz/openbmc_project/network/") + ifaceId,
+            "xyz.openbmc_project.Object.Delete", "Delete");
+    };
+
+    /**
+     * @brief Sets given HostName of the machine through D-Bus
+     *
+     * @param[in] newHostname   New name that HostName will be changed to
+     * @param[in] callback      Function that will be called after the operation
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void setHostName(const std::string &newHostname, CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            callback, "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/config",
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
+            sdbusplus::message::variant<std::string>(newHostname));
+    };
+
+    /**
+     * @brief Deletes given IPv4
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be deleted
+     * @param[in] ipIdx       index of IP in input array that should be deleted
+     * @param[in] ipHash      DBus Hash id of IP that should be deleted
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void deleteIPv4(const std::string &ifaceId, const std::string &ipHash,
+                    unsigned int ipIdx,
+                    const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        crow::connections::systemBus->async_method_call(
+            [ipIdx{std::move(ipIdx)}, asyncResp{std::move(asyncResp)}](
+                const boost::system::error_code ec) {
+                if (ec)
+                {
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue, messages::internalError(),
+                        "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
                 }
-              }
+                else
+                {
+                    asyncResp->res.jsonValue["IPv4Addresses"][ipIdx] = nullptr;
+                }
+            },
+            "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId + "/ipv4/" + ipHash,
+            "xyz.openbmc_project.Object.Delete", "Delete");
+    }
+
+    /**
+     * @brief Creates IPv4 with given data
+     *
+     * @param[in] ifaceId     Id of interface whose IP should be deleted
+     * @param[in] ipIdx       index of IP in input array that should be deleted
+     * @param[in] ipHash      DBus Hash id of IP that should be deleted
+     * @param[io] asyncResp   Response object that will be returned to client
+     *
+     * @return None
+     */
+    void createIPv4(const std::string &ifaceId, unsigned int ipIdx,
+                    uint8_t subnetMask, const std::string &gateway,
+                    const std::string &address,
+                    const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        auto createIpHandler = [ipIdx{std::move(ipIdx)},
+                                asyncResp{std::move(asyncResp)}](
+                                   const boost::system::error_code ec) {
+            if (ec)
+            {
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue, messages::internalError(),
+                    "/IPv4Addresses/" + std::to_string(ipIdx) + "/");
             }
-          }
-          // Finally make a callback with useful data
-          callback(true, ifaceList);
-        },
-        "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
-        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  };
+        };
+
+        crow::connections::systemBus->async_method_call(
+            std::move(createIpHandler), "xyz.openbmc_project.Network",
+            "/xyz/openbmc_project/network/" + ifaceId,
+            "xyz.openbmc_project.Network.IP.Create", "IP",
+            "xyz.openbmc_project.Network.IP.Protocol.IPv4", address, subnetMask,
+            gateway);
+    }
+
+    /**
+     * @brief Translates Address Origin value from D-Bus to Redfish format and
+     *        vice-versa
+     *
+     * @param[in] inputOrigin Input value that should be translated
+     * @param[in] isIPv4      True for IPv4 origins, False for IPv6
+     * @param[in] isFromDBus  True for DBus->Redfish conversion, false for
+     * reverse
+     *
+     * @return Empty string in case of failure, translated value otherwise
+     */
+    std::string translateAddressOriginBetweenDBusAndRedfish(
+        const std::string *inputOrigin, bool isIPv4, bool isFromDBus)
+    {
+        // Invalid pointer
+        if (inputOrigin == nullptr)
+        {
+            return "";
+        }
+
+        static const constexpr unsigned int firstIPv4OnlyIdx = 1;
+        static const constexpr unsigned int firstIPv6OnlyIdx = 3;
+
+        std::array<std::pair<const char *, const char *>, 6> translationTable{
+            {{"xyz.openbmc_project.Network.IP.AddressOrigin.Static", "Static"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCP"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
+              "IPv4LinkLocal"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.DHCP", "DHCPv6"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.LinkLocal",
+              "LinkLocal"},
+             {"xyz.openbmc_project.Network.IP.AddressOrigin.SLAAC", "SLAAC"}}};
+
+        for (unsigned int i = 0; i < translationTable.size(); i++)
+        {
+            // Skip unrelated
+            if (isIPv4 && i >= firstIPv6OnlyIdx)
+                break;
+            if (!isIPv4 && i >= firstIPv4OnlyIdx && i < firstIPv6OnlyIdx)
+                continue;
+
+            // When translating D-Bus to Redfish compare input to first element
+            if (isFromDBus && translationTable[i].first == *inputOrigin)
+                return translationTable[i].second;
+
+            // When translating Redfish to D-Bus compare input to second element
+            if (!isFromDBus && translationTable[i].second == *inputOrigin)
+                return translationTable[i].first;
+        }
+
+        // If we are still here, that means that value has not been found
+        return "";
+    }
+
+    /**
+     * Function that retrieves all properties for given Ethernet Interface
+     * Object
+     * from EntityManager Network Manager
+     * @param ethifaceId a eth interface id to query on DBus
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON
+     */
+    template <typename CallbackFunc>
+    void getEthernetIfaceData(const std::string &ethifaceId,
+                              CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            [this, ethifaceId{std::move(ethifaceId)},
+             callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                const GetManagedObjectsType &resp) {
+                EthernetInterfaceData ethData{};
+                std::vector<IPv4AddressData> ipv4Data;
+                ipv4Data.reserve(maxIpV4AddressesPerInterface);
+
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Network Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, ethData, ipv4Data);
+                    return;
+                }
+
+                // Find interface
+                if (resp.find("/xyz/openbmc_project/network/" + ethifaceId) ==
+                    resp.end())
+                {
+                    // Interface has not been found
+                    callback(false, ethData, ipv4Data);
+                    return;
+                }
+
+                extractEthernetInterfaceData(ethifaceId, resp, ethData);
+                extractIPv4Data(ethifaceId, resp, ipv4Data);
+
+                // Fix global GW
+                for (IPv4AddressData &ipv4 : ipv4Data)
+                {
+                    if ((ipv4.global) && ((ipv4.gateway == nullptr) ||
+                                          (*ipv4.gateway == "0.0.0.0")))
+                    {
+                        ipv4.gateway = ethData.defaultGateway;
+                    }
+                }
+
+                // Finally make a callback with useful data
+                callback(true, ethData, ipv4Data);
+            },
+            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    };
+
+    /**
+     * Function that retrieves all Ethernet Interfaces available through Network
+     * Manager
+     * @param callback a function that shall be called to convert Dbus output
+     * into JSON.
+     */
+    template <typename CallbackFunc>
+    void getEthernetIfaceList(CallbackFunc &&callback)
+    {
+        crow::connections::systemBus->async_method_call(
+            [this, callback{std::move(callback)}](
+                const boost::system::error_code error_code,
+                GetManagedObjectsType &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // ethernet interfaces
+                std::vector<std::string> ifaceList;
+                ifaceList.reserve(resp.size());
+                if (error_code)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Network Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, ifaceList);
+                    return;
+                }
+
+                // Iterate over all retrieved ObjectPaths.
+                for (auto &objpath : resp)
+                {
+                    // And all interfaces available for certain ObjectPath.
+                    for (auto &interface : objpath.second)
+                    {
+                        // If interface is
+                        // xyz.openbmc_project.Network.EthernetInterface, this
+                        // is what we're looking for.
+                        if (interface.first ==
+                            "xyz.openbmc_project.Network.EthernetInterface")
+                        {
+                            // Cut out everything until last "/", ...
+                            const std::string &ifaceId =
+                                static_cast<const std::string &>(objpath.first);
+                            std::size_t lastPos = ifaceId.rfind("/");
+                            if (lastPos != std::string::npos)
+                            {
+                                // and put it into output vector.
+                                ifaceList.emplace_back(
+                                    ifaceId.substr(lastPos + 1));
+                            }
+                        }
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, ifaceList);
+            },
+            "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    };
 };
 
 /**
  * EthernetCollection derived class for delivering Ethernet Collection Schema
  */
-class EthernetCollection : public Node {
- public:
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  EthernetCollection(CrowApp &app)
-      : Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/") {
-    Node::json["@odata.type"] =
-        "#EthernetInterfaceCollection.EthernetInterfaceCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/EthernetInterfaces";
-    Node::json["Name"] = "Ethernet Network Interface Collection";
-    Node::json["Description"] =
-        "Collection of EthernetInterfaces for this Manager";
-
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([&, managerId{std::move(managerId)} ](
-        const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        nlohmann::json ifaceArray = nlohmann::json::array();
-        for (const std::string &ifaceItem : iface_list) {
-          ifaceArray.push_back(
-              {{"@odata.id", "/redfish/v1/Managers/" + managerId +
-                                 "/EthernetInterfaces/" + ifaceItem}});
-        }
-        Node::json["Members"] = ifaceArray;
-        Node::json["Members@odata.count"] = ifaceArray.size();
+class EthernetCollection : public Node
+{
+  public:
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    EthernetCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/")
+    {
+        Node::json["@odata.type"] =
+            "#EthernetInterfaceCollection.EthernetInterfaceCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection";
         Node::json["@odata.id"] =
-            "/redfish/v1/Managers/" + managerId + "/EthernetInterfaces";
-        res.jsonValue = Node::json;
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-      }
-      res.end();
-    });
-  }
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces";
+        Node::json["Name"] = "Ethernet Network Interface Collection";
+        Node::json["Description"] =
+            "Collection of EthernetInterfaces for this Manager";
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
+
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    nlohmann::json ifaceArray = nlohmann::json::array();
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        ifaceArray.push_back(
+                            {{"@odata.id", "/redfish/v1/Managers/" + managerId +
+                                               "/EthernetInterfaces/" +
+                                               ifaceItem}});
+                    }
+                    Node::json["Members"] = ifaceArray;
+                    Node::json["Members@odata.count"] = ifaceArray.size();
+                    Node::json["@odata.id"] = "/redfish/v1/Managers/" +
+                                              managerId + "/EthernetInterfaces";
+                    res.jsonValue = Node::json;
+                }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 /**
  * EthernetInterface derived class for delivering Ethernet Schema
  */
-class EthernetInterface : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  EthernetInterface(CrowApp &app)
-      : Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/",
-             std::string()) {
-    Node::json["@odata.type"] = "#EthernetInterface.v1_2_0.EthernetInterface";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#EthernetInterface.EthernetInterface";
-    Node::json["Name"] = "Manager Ethernet Interface";
-    Node::json["Description"] = "Management Network Interface";
+class EthernetInterface : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    EthernetInterface(CrowApp &app) :
+        Node(app, "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/",
+             std::string())
+    {
+        Node::json["@odata.type"] =
+            "#EthernetInterface.v1_2_0.EthernetInterface";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#EthernetInterface.EthernetInterface";
+        Node::json["Name"] = "Manager Ethernet Interface";
+        Node::json["Description"] = "Management Network Interface";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
-  // TODO(kkowalsk) Find a suitable class/namespace for this
-  static void handleVlanPatch(const std::string &ifaceId,
-                              const nlohmann::json &input,
-                              const EthernetInterfaceData &eth_data,
-                              const std::string &pathPrefix,
-                              const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (!input.is_object()) {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "VLAN"), pathPrefix);
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
-    nlohmann::json &paramsJson =
-        (pathPrefix == "/")
-            ? asyncResp->res.jsonValue
-            : asyncResp->res.jsonValue[nlohmann::json_pointer<nlohmann::json>(
-                  pathPrefix)];
-    bool inputVlanEnabled;
-    uint64_t inputVlanId;
-
-    json_util::Result inputVlanEnabledState = json_util::getBool(
-        "VLANEnable", input, inputVlanEnabled,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.jsonValue, std::string(pathStart + "/VLANEnable"));
-    json_util::Result inputVlanIdState = json_util::getUnsigned(
-        "VLANId", input, inputVlanId,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
-        asyncResp->res.jsonValue, std::string(pathStart + "/VLANId"));
-    bool inputInvalid = false;
-
-    // Do not proceed if fields in VLAN object were of wrong type
-    if (inputVlanEnabledState == json_util::Result::WRONG_TYPE ||
-        inputVlanIdState == json_util::Result::WRONG_TYPE) {
-      return;
-    }
-
-    // Verify input
-    if (eth_data.vlanId == nullptr) {
-      // This interface is not a VLAN. Cannot do anything with it
-      // TODO(kkowalsk) Change this message
-      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                 messages::propertyMissing("VLANEnable"),
-                                 pathPrefix);
-
-      inputInvalid = true;
-    } else {
-      // Load actual data into field values if they were not provided
-      if (inputVlanEnabledState == json_util::Result::NOT_EXIST) {
-        inputVlanEnabled = true;
-      }
-
-      if (inputVlanIdState == json_util::Result::NOT_EXIST) {
-        inputVlanId = *eth_data.vlanId;
-      }
-    }
-
-    // Do not proceed if input has not been valid
-    if (inputInvalid) {
-      return;
-    }
-
-    // VLAN is configured on the interface
-    if (inputVlanEnabled == true && inputVlanId != *eth_data.vlanId) {
-      // Change VLAN Id
-      paramsJson["VLANId"] = inputVlanId;
-      OnDemandEthernetProvider::changeVlanId(
-          ifaceId, static_cast<uint32_t>(inputVlanId),
-          [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              messages::addMessageToJson(asyncResp->res.jsonValue,
-                                         messages::internalError(), pathPrefix);
-            } else {
-              paramsJson["VLANEnable"] = true;
-            }
-          });
-    } else if (inputVlanEnabled == false) {
-      // Disable VLAN
-      OnDemandEthernetProvider::disableVlan(
-          ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)} ](
-                       const boost::system::error_code ec) {
-            if (ec) {
-              messages::addMessageToJson(asyncResp->res.jsonValue,
-                                         messages::internalError(), pathPrefix);
-            } else {
-              paramsJson["VLANEnable"] = false;
-            }
-          });
-    }
-  }
-
- private:
-  void handleHostnamePatch(const nlohmann::json &input,
-                           const EthernetInterfaceData &eth_data,
-                           const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (input.is_string()) {
-      std::string newHostname = input.get<std::string>();
-
-      if (eth_data.hostname == nullptr || newHostname != *eth_data.hostname) {
-        // Change hostname
-        ethernetProvider.setHostName(
-            newHostname,
-            [asyncResp, newHostname](const boost::system::error_code ec) {
-              if (ec) {
-                messages::addMessageToJson(asyncResp->res.jsonValue,
-                                           messages::internalError(),
-                                           "/HostName");
-              } else {
-                asyncResp->res.jsonValue["HostName"] = newHostname;
-              }
-            });
-      }
-    } else {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "HostName"),
-          "/HostName");
-    }
-  }
-
-  void handleIPv4Patch(const std::string &ifaceId, const nlohmann::json &input,
-                       const std::vector<IPv4AddressData> &ipv4_data,
-                       const std::shared_ptr<AsyncResp> &asyncResp) {
-    if (!input.is_array()) {
-      messages::addMessageToJson(
-          asyncResp->res.jsonValue,
-          messages::propertyValueTypeError(input.dump(), "IPv4Addresses"),
-          "/IPv4Addresses");
-      return;
-    }
-
-    // According to Redfish PATCH definition, size must be at least equal
-    if (input.size() < ipv4_data.size()) {
-      // TODO(kkowalsk) This should be a message indicating that not enough
-      // data has been provided
-      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                 messages::internalError(), "/IPv4Addresses");
-      return;
-    }
-
-    json_util::Result addressFieldState;
-    json_util::Result subnetMaskFieldState;
-    json_util::Result addressOriginFieldState;
-    json_util::Result gatewayFieldState;
-    const std::string *addressFieldValue;
-    const std::string *subnetMaskFieldValue;
-    const std::string *addressOriginFieldValue = nullptr;
-    const std::string *gatewayFieldValue;
-    uint8_t subnetMaskAsPrefixLength;
-    std::string addressOriginInDBusFormat;
-
-    bool errorDetected = false;
-    for (unsigned int entryIdx = 0; entryIdx < input.size(); entryIdx++) {
-      // Check that entry is not of some unexpected type
-      if (!input[entryIdx].is_object() && !input[entryIdx].is_null()) {
-        // Invalid object type
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueTypeError(input[entryIdx].dump(),
-                                             "IPv4Address"),
-            "/IPv4Addresses/" + std::to_string(entryIdx));
-
-        continue;
-      }
-
-      // Try to load fields
-      addressFieldState = json_util::getString(
-          "Address", input[entryIdx], addressFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-      subnetMaskFieldState = json_util::getString(
-          "SubnetMask", input[entryIdx], subnetMaskFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-      addressOriginFieldState = json_util::getString(
-          "AddressOrigin", input[entryIdx], addressOriginFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-      gatewayFieldState = json_util::getString(
-          "Gateway", input[entryIdx], gatewayFieldValue,
-          static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-          asyncResp->res.jsonValue,
-          "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-
-      if (addressFieldState == json_util::Result::WRONG_TYPE ||
-          subnetMaskFieldState == json_util::Result::WRONG_TYPE ||
-          addressOriginFieldState == json_util::Result::WRONG_TYPE ||
-          gatewayFieldState == json_util::Result::WRONG_TYPE) {
-        return;
-      }
-
-      if (addressFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(*addressFieldValue)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*addressFieldValue, "Address"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-      }
-
-      if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(
-              *subnetMaskFieldValue, &subnetMaskAsPrefixLength)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*subnetMaskFieldValue,
-                                               "SubnetMask"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-      }
-
-      // get Address origin in proper format
-      addressOriginInDBusFormat =
-          ethernetProvider.translateAddressOriginBetweenDBusAndRedfish(
-              addressOriginFieldValue, true, false);
-
-      if (addressOriginFieldState == json_util::Result::SUCCESS &&
-          addressOriginInDBusFormat.empty()) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueNotInList(*addressOriginFieldValue,
-                                             "AddressOrigin"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-      }
-
-      if (gatewayFieldState == json_util::Result::SUCCESS &&
-          !ethernetProvider.ipv4VerifyIpAndGetBitcount(*gatewayFieldValue)) {
-        errorDetected = true;
-        messages::addMessageToJson(
-            asyncResp->res.jsonValue,
-            messages::propertyValueFormatError(*gatewayFieldValue, "Gateway"),
-            "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-      }
-
-      // If any error occured do not proceed with current entry, but do not
-      // end loop
-      if (errorDetected) {
-        errorDetected = false;
-        continue;
-      }
-
-      if (entryIdx >= ipv4_data.size()) {
-        asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] = input[entryIdx];
-
-        // Verify that all field were provided
-        if (addressFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("Address"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
-        }
-
-        if (subnetMaskFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("SubnetMask"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
-        }
-
-        if (addressOriginFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue,
-              messages::propertyMissing("AddressOrigin"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/AddressOrigin");
-        }
-
-        if (gatewayFieldState == json_util::Result::NOT_EXIST) {
-          errorDetected = true;
-          messages::addMessageToJson(
-              asyncResp->res.jsonValue, messages::propertyMissing("Gateway"),
-              "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
-        }
-
-        // If any error occured do not proceed with current entry, but do not
-        // end loop
-        if (errorDetected) {
-          errorDetected = false;
-          continue;
-        }
-
-        // Create IPv4 with provided data
-        ethernetProvider.createIPv4(ifaceId, entryIdx, subnetMaskAsPrefixLength,
-                                    *gatewayFieldValue, *addressFieldValue,
-                                    asyncResp);
-      } else {
-        // Existing object that should be modified/deleted/remain unchanged
-        if (input[entryIdx].is_null()) {
-          // Object should be deleted
-          ethernetProvider.deleteIPv4(ifaceId, ipv4_data[entryIdx].id, entryIdx,
-                                      asyncResp);
-        } else if (input[entryIdx].is_object()) {
-          if (input[entryIdx].size() == 0) {
-            // Object shall remain unchanged
-            continue;
-          }
-
-          // Apply changes
-          if (addressFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].address != nullptr &&
-              *ipv4_data[entryIdx].address != *addressFieldValue) {
-            ethernetProvider.changeIPv4AddressProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id, "Address",
-                *addressFieldValue, asyncResp);
-          }
-
-          if (subnetMaskFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].netmask != *subnetMaskFieldValue) {
-            ethernetProvider.changeIPv4SubnetMaskProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                *subnetMaskFieldValue, subnetMaskAsPrefixLength, asyncResp);
-          }
-
-          if (addressOriginFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].origin != *addressFieldValue) {
-            ethernetProvider.changeIPv4Origin(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id,
-                *addressOriginFieldValue, addressOriginInDBusFormat, asyncResp);
-          }
-
-          if (gatewayFieldState == json_util::Result::SUCCESS &&
-              ipv4_data[entryIdx].gateway != nullptr &&
-              *ipv4_data[entryIdx].gateway != *gatewayFieldValue) {
-            ethernetProvider.changeIPv4AddressProperty(
-                ifaceId, entryIdx, ipv4_data[entryIdx].id, "Gateway",
-                *gatewayFieldValue, asyncResp);
-          }
-        }
-      }
-    }
-  }
-
-  nlohmann::json parseInterfaceData(
-      const std::string &ifaceId, const EthernetInterfaceData &eth_data,
-      const std::vector<IPv4AddressData> &ipv4_data) {
-    // Copy JSON object to avoid race condition
-    nlohmann::json jsonResponse(Node::json);
-
-    // Fill out obvious data...
-    jsonResponse["Id"] = ifaceId;
-    jsonResponse["@odata.id"] =
-        "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId;
-
-    // ... then the one from DBus, regarding eth iface...
-    if (eth_data.speed != nullptr) jsonResponse["SpeedMbps"] = *eth_data.speed;
-
-    if (eth_data.macAddress != nullptr)
-      jsonResponse["MACAddress"] = *eth_data.macAddress;
-
-    if (eth_data.hostname != nullptr)
-      jsonResponse["HostName"] = *eth_data.hostname;
-
-    if (eth_data.vlanId != nullptr) {
-      nlohmann::json &vlanObj = jsonResponse["VLAN"];
-      vlanObj["VLANEnable"] = true;
-      vlanObj["VLANId"] = *eth_data.vlanId;
-    } else {
-      nlohmann::json &vlanObj = jsonResponse["VLANs"];
-      vlanObj["@odata.id"] =
-          "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId +
-          "/VLANs";
-    }
-
-    // ... at last, check if there are IPv4 data and prepare appropriate
-    // collection
-    if (ipv4_data.size() > 0) {
-      nlohmann::json ipv4Array = nlohmann::json::array();
-      for (auto &ipv4Config : ipv4_data) {
-        nlohmann::json jsonIpv4;
-        if (ipv4Config.address != nullptr) {
-          jsonIpv4["Address"] = *ipv4Config.address;
-          if (ipv4Config.gateway != nullptr)
-            jsonIpv4["Gateway"] = *ipv4Config.gateway;
-
-          jsonIpv4["AddressOrigin"] = ipv4Config.origin;
-          jsonIpv4["SubnetMask"] = ipv4Config.netmask;
-
-          ipv4Array.push_back(std::move(jsonIpv4));
-        }
-      }
-      jsonResponse["IPv4Addresses"] = std::move(ipv4Array);
-    }
-
-    return jsonResponse;
-  }
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &ifaceId = params[0];
-
-    // get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId,
-        [&, ifaceId](const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success) {
-            res.jsonValue = parseInterfaceData(ifaceId, eth_data, ipv4_data);
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("EthernetInterface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-          }
-          res.end();
-        });
-  }
-
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &ifaceId = params[0];
-
-    nlohmann::json patchReq;
-
-    if (!json_util::processJsonFromRequest(res, req, patchReq)) {
-      return;
-    }
-
-    // get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, ifaceId, patchReq = std::move(patchReq) ](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (!success) {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-            res.end();
-
+    // TODO(kkowalsk) Find a suitable class/namespace for this
+    static void handleVlanPatch(const std::string &ifaceId,
+                                const nlohmann::json &input,
+                                const EthernetInterfaceData &eth_data,
+                                const std::string &pathPrefix,
+                                const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (!input.is_object())
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "VLAN"),
+                pathPrefix);
             return;
-          }
+        }
 
-          res.jsonValue = parseInterfaceData(ifaceId, eth_data, ipv4_data);
+        const std::string pathStart = (pathPrefix == "/") ? "" : pathPrefix;
+        nlohmann::json &paramsJson =
+            (pathPrefix == "/")
+                ? asyncResp->res.jsonValue
+                : asyncResp->res
+                      .jsonValue[nlohmann::json_pointer<nlohmann::json>(
+                          pathPrefix)];
+        bool inputVlanEnabled;
+        uint64_t inputVlanId;
 
-          std::shared_ptr<AsyncResp> asyncResp =
-              std::make_shared<AsyncResp>(res);
+        json_util::Result inputVlanEnabledState = json_util::getBool(
+            "VLANEnable", input, inputVlanEnabled,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
+            asyncResp->res.jsonValue, std::string(pathStart + "/VLANEnable"));
+        json_util::Result inputVlanIdState = json_util::getUnsigned(
+            "VLANId", input, inputVlanId,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR),
+            asyncResp->res.jsonValue, std::string(pathStart + "/VLANId"));
+        bool inputInvalid = false;
 
-          for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
-               ++propertyIt) {
-            if (propertyIt.key() == "VLAN") {
-              handleVlanPatch(ifaceId, propertyIt.value(), eth_data, "/VLAN",
-                              asyncResp);
-            } else if (propertyIt.key() == "HostName") {
-              handleHostnamePatch(propertyIt.value(), eth_data, asyncResp);
-            } else if (propertyIt.key() == "IPv4Addresses") {
-              handleIPv4Patch(ifaceId, propertyIt.value(), ipv4_data,
-                              asyncResp);
-            } else if (propertyIt.key() == "IPv6Addresses") {
-              // TODO(kkowalsk) IPv6 Not supported on D-Bus yet
-              messages::addMessageToJsonRoot(
-                  res.jsonValue,
-                  messages::propertyNotWritable(propertyIt.key()));
-            } else {
-              auto fieldInJsonIt = res.jsonValue.find(propertyIt.key());
+        // Do not proceed if fields in VLAN object were of wrong type
+        if (inputVlanEnabledState == json_util::Result::WRONG_TYPE ||
+            inputVlanIdState == json_util::Result::WRONG_TYPE)
+        {
+            return;
+        }
 
-              if (fieldInJsonIt == res.jsonValue.end()) {
-                // Field not in scope of defined fields
-                messages::addMessageToJsonRoot(
-                    res.jsonValue, messages::propertyUnknown(propertyIt.key()));
-              } else if (*fieldInJsonIt != *propertyIt) {
-                // User attempted to modify non-writable field
-                messages::addMessageToJsonRoot(
-                    res.jsonValue,
-                    messages::propertyNotWritable(propertyIt.key()));
-              }
+        // Verify input
+        if (eth_data.vlanId == nullptr)
+        {
+            // This interface is not a VLAN. Cannot do anything with it
+            // TODO(kkowalsk) Change this message
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::propertyMissing("VLANEnable"),
+                                       pathPrefix);
+
+            inputInvalid = true;
+        }
+        else
+        {
+            // Load actual data into field values if they were not provided
+            if (inputVlanEnabledState == json_util::Result::NOT_EXIST)
+            {
+                inputVlanEnabled = true;
             }
-          }
-        });
-  }
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+            if (inputVlanIdState == json_util::Result::NOT_EXIST)
+            {
+                inputVlanId = *eth_data.vlanId;
+            }
+        }
+
+        // Do not proceed if input has not been valid
+        if (inputInvalid)
+        {
+            return;
+        }
+
+        // VLAN is configured on the interface
+        if (inputVlanEnabled == true && inputVlanId != *eth_data.vlanId)
+        {
+            // Change VLAN Id
+            paramsJson["VLANId"] = inputVlanId;
+            OnDemandEthernetProvider::changeVlanId(
+                ifaceId, static_cast<uint32_t>(inputVlanId),
+                [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        messages::addMessageToJson(asyncResp->res.jsonValue,
+                                                   messages::internalError(),
+                                                   pathPrefix);
+                    }
+                    else
+                    {
+                        paramsJson["VLANEnable"] = true;
+                    }
+                });
+        }
+        else if (inputVlanEnabled == false)
+        {
+            // Disable VLAN
+            OnDemandEthernetProvider::disableVlan(
+                ifaceId, [&, asyncResp, pathPrefx{std::move(pathPrefix)}](
+                             const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        messages::addMessageToJson(asyncResp->res.jsonValue,
+                                                   messages::internalError(),
+                                                   pathPrefix);
+                    }
+                    else
+                    {
+                        paramsJson["VLANEnable"] = false;
+                    }
+                });
+        }
+    }
+
+  private:
+    void handleHostnamePatch(const nlohmann::json &input,
+                             const EthernetInterfaceData &eth_data,
+                             const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (input.is_string())
+        {
+            std::string newHostname = input.get<std::string>();
+
+            if (eth_data.hostname == nullptr ||
+                newHostname != *eth_data.hostname)
+            {
+                // Change hostname
+                ethernetProvider.setHostName(
+                    newHostname, [asyncResp, newHostname](
+                                     const boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            messages::addMessageToJson(
+                                asyncResp->res.jsonValue,
+                                messages::internalError(), "/HostName");
+                        }
+                        else
+                        {
+                            asyncResp->res.jsonValue["HostName"] = newHostname;
+                        }
+                    });
+            }
+        }
+        else
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "HostName"),
+                "/HostName");
+        }
+    }
+
+    void handleIPv4Patch(const std::string &ifaceId,
+                         const nlohmann::json &input,
+                         const std::vector<IPv4AddressData> &ipv4_data,
+                         const std::shared_ptr<AsyncResp> &asyncResp)
+    {
+        if (!input.is_array())
+        {
+            messages::addMessageToJson(
+                asyncResp->res.jsonValue,
+                messages::propertyValueTypeError(input.dump(), "IPv4Addresses"),
+                "/IPv4Addresses");
+            return;
+        }
+
+        // According to Redfish PATCH definition, size must be at least equal
+        if (input.size() < ipv4_data.size())
+        {
+            // TODO(kkowalsk) This should be a message indicating that not
+            // enough data has been provided
+            messages::addMessageToJson(asyncResp->res.jsonValue,
+                                       messages::internalError(),
+                                       "/IPv4Addresses");
+            return;
+        }
+
+        json_util::Result addressFieldState;
+        json_util::Result subnetMaskFieldState;
+        json_util::Result addressOriginFieldState;
+        json_util::Result gatewayFieldState;
+        const std::string *addressFieldValue;
+        const std::string *subnetMaskFieldValue;
+        const std::string *addressOriginFieldValue = nullptr;
+        const std::string *gatewayFieldValue;
+        uint8_t subnetMaskAsPrefixLength;
+        std::string addressOriginInDBusFormat;
+
+        bool errorDetected = false;
+        for (unsigned int entryIdx = 0; entryIdx < input.size(); entryIdx++)
+        {
+            // Check that entry is not of some unexpected type
+            if (!input[entryIdx].is_object() && !input[entryIdx].is_null())
+            {
+                // Invalid object type
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueTypeError(input[entryIdx].dump(),
+                                                     "IPv4Address"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx));
+
+                continue;
+            }
+
+            // Try to load fields
+            addressFieldState = json_util::getString(
+                "Address", input[entryIdx], addressFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
+            subnetMaskFieldState = json_util::getString(
+                "SubnetMask", input[entryIdx], subnetMaskFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/SubnetMask");
+            addressOriginFieldState = json_util::getString(
+                "AddressOrigin", input[entryIdx], addressOriginFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) +
+                    "/AddressOrigin");
+            gatewayFieldState = json_util::getString(
+                "Gateway", input[entryIdx], gatewayFieldValue,
+                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                asyncResp->res.jsonValue,
+                "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
+
+            if (addressFieldState == json_util::Result::WRONG_TYPE ||
+                subnetMaskFieldState == json_util::Result::WRONG_TYPE ||
+                addressOriginFieldState == json_util::Result::WRONG_TYPE ||
+                gatewayFieldState == json_util::Result::WRONG_TYPE)
+            {
+                return;
+            }
+
+            if (addressFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *addressFieldValue))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*addressFieldValue,
+                                                       "Address"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Address");
+            }
+
+            if (subnetMaskFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *subnetMaskFieldValue, &subnetMaskAsPrefixLength))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*subnetMaskFieldValue,
+                                                       "SubnetMask"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) +
+                        "/SubnetMask");
+            }
+
+            // get Address origin in proper format
+            addressOriginInDBusFormat =
+                ethernetProvider.translateAddressOriginBetweenDBusAndRedfish(
+                    addressOriginFieldValue, true, false);
+
+            if (addressOriginFieldState == json_util::Result::SUCCESS &&
+                addressOriginInDBusFormat.empty())
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueNotInList(*addressOriginFieldValue,
+                                                     "AddressOrigin"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) +
+                        "/AddressOrigin");
+            }
+
+            if (gatewayFieldState == json_util::Result::SUCCESS &&
+                !ethernetProvider.ipv4VerifyIpAndGetBitcount(
+                    *gatewayFieldValue))
+            {
+                errorDetected = true;
+                messages::addMessageToJson(
+                    asyncResp->res.jsonValue,
+                    messages::propertyValueFormatError(*gatewayFieldValue,
+                                                       "Gateway"),
+                    "/IPv4Addresses/" + std::to_string(entryIdx) + "/Gateway");
+            }
+
+            // If any error occured do not proceed with current entry, but do
+            // not end loop
+            if (errorDetected)
+            {
+                errorDetected = false;
+                continue;
+            }
+
+            if (entryIdx >= ipv4_data.size())
+            {
+                asyncResp->res.jsonValue["IPv4Addresses"][entryIdx] =
+                    input[entryIdx];
+
+                // Verify that all field were provided
+                if (addressFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Address"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/Address");
+                }
+
+                if (subnetMaskFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("SubnetMask"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/SubnetMask");
+                }
+
+                if (addressOriginFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("AddressOrigin"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/AddressOrigin");
+                }
+
+                if (gatewayFieldState == json_util::Result::NOT_EXIST)
+                {
+                    errorDetected = true;
+                    messages::addMessageToJson(
+                        asyncResp->res.jsonValue,
+                        messages::propertyMissing("Gateway"),
+                        "/IPv4Addresses/" + std::to_string(entryIdx) +
+                            "/Gateway");
+                }
+
+                // If any error occured do not proceed with current entry, but
+                // do not end loop
+                if (errorDetected)
+                {
+                    errorDetected = false;
+                    continue;
+                }
+
+                // Create IPv4 with provided data
+                ethernetProvider.createIPv4(
+                    ifaceId, entryIdx, subnetMaskAsPrefixLength,
+                    *gatewayFieldValue, *addressFieldValue, asyncResp);
+            }
+            else
+            {
+                // Existing object that should be modified/deleted/remain
+                // unchanged
+                if (input[entryIdx].is_null())
+                {
+                    // Object should be deleted
+                    ethernetProvider.deleteIPv4(ifaceId, ipv4_data[entryIdx].id,
+                                                entryIdx, asyncResp);
+                }
+                else if (input[entryIdx].is_object())
+                {
+                    if (input[entryIdx].size() == 0)
+                    {
+                        // Object shall remain unchanged
+                        continue;
+                    }
+
+                    // Apply changes
+                    if (addressFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].address != nullptr &&
+                        *ipv4_data[entryIdx].address != *addressFieldValue)
+                    {
+                        ethernetProvider.changeIPv4AddressProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            "Address", *addressFieldValue, asyncResp);
+                    }
+
+                    if (subnetMaskFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].netmask != *subnetMaskFieldValue)
+                    {
+                        ethernetProvider.changeIPv4SubnetMaskProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            *subnetMaskFieldValue, subnetMaskAsPrefixLength,
+                            asyncResp);
+                    }
+
+                    if (addressOriginFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].origin != *addressFieldValue)
+                    {
+                        ethernetProvider.changeIPv4Origin(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            *addressOriginFieldValue, addressOriginInDBusFormat,
+                            asyncResp);
+                    }
+
+                    if (gatewayFieldState == json_util::Result::SUCCESS &&
+                        ipv4_data[entryIdx].gateway != nullptr &&
+                        *ipv4_data[entryIdx].gateway != *gatewayFieldValue)
+                    {
+                        ethernetProvider.changeIPv4AddressProperty(
+                            ifaceId, entryIdx, ipv4_data[entryIdx].id,
+                            "Gateway", *gatewayFieldValue, asyncResp);
+                    }
+                }
+            }
+        }
+    }
+
+    nlohmann::json
+        parseInterfaceData(const std::string &ifaceId,
+                           const EthernetInterfaceData &eth_data,
+                           const std::vector<IPv4AddressData> &ipv4_data)
+    {
+        // Copy JSON object to avoid race condition
+        nlohmann::json jsonResponse(Node::json);
+
+        // Fill out obvious data...
+        jsonResponse["Id"] = ifaceId;
+        jsonResponse["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId;
+
+        // ... then the one from DBus, regarding eth iface...
+        if (eth_data.speed != nullptr)
+            jsonResponse["SpeedMbps"] = *eth_data.speed;
+
+        if (eth_data.macAddress != nullptr)
+            jsonResponse["MACAddress"] = *eth_data.macAddress;
+
+        if (eth_data.hostname != nullptr)
+            jsonResponse["HostName"] = *eth_data.hostname;
+
+        if (eth_data.vlanId != nullptr)
+        {
+            nlohmann::json &vlanObj = jsonResponse["VLAN"];
+            vlanObj["VLANEnable"] = true;
+            vlanObj["VLANId"] = *eth_data.vlanId;
+        }
+        else
+        {
+            nlohmann::json &vlanObj = jsonResponse["VLANs"];
+            vlanObj["@odata.id"] =
+                "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + ifaceId +
+                "/VLANs";
+        }
+
+        // ... at last, check if there are IPv4 data and prepare appropriate
+        // collection
+        if (ipv4_data.size() > 0)
+        {
+            nlohmann::json ipv4Array = nlohmann::json::array();
+            for (auto &ipv4Config : ipv4_data)
+            {
+                nlohmann::json jsonIpv4;
+                if (ipv4Config.address != nullptr)
+                {
+                    jsonIpv4["Address"] = *ipv4Config.address;
+                    if (ipv4Config.gateway != nullptr)
+                        jsonIpv4["Gateway"] = *ipv4Config.gateway;
+
+                    jsonIpv4["AddressOrigin"] = ipv4Config.origin;
+                    jsonIpv4["SubnetMask"] = ipv4Config.netmask;
+
+                    ipv4Array.push_back(std::move(jsonIpv4));
+                }
+            }
+            jsonResponse["IPv4Addresses"] = std::move(ipv4Array);
+        }
+
+        return jsonResponse;
+    }
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &ifaceId = params[0];
+
+        // get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, ifaceId](const bool &success,
+                         const EthernetInterfaceData &eth_data,
+                         const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success)
+                {
+                    res.jsonValue =
+                        parseInterfaceData(ifaceId, eth_data, ipv4_data);
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "EthernetInterface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                }
+                res.end();
+            });
+    }
+
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &ifaceId = params[0];
+
+        nlohmann::json patchReq;
+
+        if (!json_util::processJsonFromRequest(res, req, patchReq))
+        {
+            return;
+        }
+
+        // get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, ifaceId, patchReq = std::move(patchReq)](
+                const bool &success, const EthernetInterfaceData &eth_data,
+                const std::vector<IPv4AddressData> &ipv4_data) {
+                if (!success)
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+
+                    return;
+                }
+
+                res.jsonValue =
+                    parseInterfaceData(ifaceId, eth_data, ipv4_data);
+
+                std::shared_ptr<AsyncResp> asyncResp =
+                    std::make_shared<AsyncResp>(res);
+
+                for (auto propertyIt = patchReq.begin();
+                     propertyIt != patchReq.end(); ++propertyIt)
+                {
+                    if (propertyIt.key() == "VLAN")
+                    {
+                        handleVlanPatch(ifaceId, propertyIt.value(), eth_data,
+                                        "/VLAN", asyncResp);
+                    }
+                    else if (propertyIt.key() == "HostName")
+                    {
+                        handleHostnamePatch(propertyIt.value(), eth_data,
+                                            asyncResp);
+                    }
+                    else if (propertyIt.key() == "IPv4Addresses")
+                    {
+                        handleIPv4Patch(ifaceId, propertyIt.value(), ipv4_data,
+                                        asyncResp);
+                    }
+                    else if (propertyIt.key() == "IPv6Addresses")
+                    {
+                        // TODO(kkowalsk) IPv6 Not supported on D-Bus yet
+                        messages::addMessageToJsonRoot(
+                            res.jsonValue,
+                            messages::propertyNotWritable(propertyIt.key()));
+                    }
+                    else
+                    {
+                        auto fieldInJsonIt =
+                            res.jsonValue.find(propertyIt.key());
+
+                        if (fieldInJsonIt == res.jsonValue.end())
+                        {
+                            // Field not in scope of defined fields
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue,
+                                messages::propertyUnknown(propertyIt.key()));
+                        }
+                        else if (*fieldInJsonIt != *propertyIt)
+                        {
+                            // User attempted to modify non-writable field
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue, messages::propertyNotWritable(
+                                                   propertyIt.key()));
+                        }
+                    }
+                }
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 class VlanNetworkInterfaceCollection;
@@ -1350,422 +1585,499 @@
 /**
  * VlanNetworkInterface derived class for delivering VLANNetworkInterface Schema
  */
-class VlanNetworkInterface : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  template <typename CrowApp>
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  VlanNetworkInterface(CrowApp &app)
-      : Node(
+class VlanNetworkInterface : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    template <typename CrowApp>
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    VlanNetworkInterface(CrowApp &app) :
+        Node(
             app,
             "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/<str>",
-            std::string(), std::string()) {
-    Node::json["@odata.type"] =
-        "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
-    Node::json["Name"] = "VLAN Network Interface";
+            std::string(), std::string())
+    {
+        Node::json["@odata.type"] =
+            "#VLanNetworkInterface.v1_1_0.VLanNetworkInterface";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#VLanNetworkInterface.VLanNetworkInterface";
+        Node::json["Name"] = "VLAN Network Interface";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  nlohmann::json parseInterfaceData(
-      const std::string &parent_ifaceId, const std::string &ifaceId,
-      const EthernetInterfaceData &eth_data,
-      const std::vector<IPv4AddressData> &ipv4_data) {
-    // Copy JSON object to avoid race condition
-    nlohmann::json jsonResponse(Node::json);
-
-    // Fill out obvious data...
-    jsonResponse["Id"] = ifaceId;
-    jsonResponse["@odata.id"] =
-        "/redfish/v1/Managers/openbmc/EthernetInterfaces/" + parent_ifaceId +
-        "/VLANs/" + ifaceId;
-
-    jsonResponse["VLANEnable"] = true;
-    jsonResponse["VLANId"] = *eth_data.vlanId;
-
-    return jsonResponse;
-  }
-
-  bool verifyNames(crow::Response &res, const std::string &parent,
-                   const std::string &iface) {
-    if (!boost::starts_with(iface, parent + "_")) {
-      messages::addMessageToErrorJson(
-          res.jsonValue,
-          messages::resourceNotFound("VLAN Network Interface", iface));
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-
-      return false;
-    } else {
-      return true;
-    }
-  }
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // TODO(Pawel) this shall be parametrized call (two params) to get
-    // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
-    // Check if there is required param, truly entering this shall be
-    // impossible.
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
+  private:
+    nlohmann::json
+        parseInterfaceData(const std::string &parent_ifaceId,
+                           const std::string &ifaceId,
+                           const EthernetInterfaceData &eth_data,
+                           const std::vector<IPv4AddressData> &ipv4_data)
+    {
+        // Copy JSON object to avoid race condition
+        nlohmann::json jsonResponse(Node::json);
 
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
+        // Fill out obvious data...
+        jsonResponse["Id"] = ifaceId;
+        jsonResponse["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/EthernetInterfaces/" +
+            parent_ifaceId + "/VLANs/" + ifaceId;
+
+        jsonResponse["VLANEnable"] = true;
+        jsonResponse["VLANId"] = *eth_data.vlanId;
+
+        return jsonResponse;
     }
 
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success && eth_data.vlanId != nullptr) {
-            res.jsonValue =
-                parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object, and
-            // other errors
+    bool verifyNames(crow::Response &res, const std::string &parent,
+                     const std::string &iface)
+    {
+        if (!boost::starts_with(iface, parent + "_"))
+        {
             messages::addMessageToErrorJson(
                 res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
-          }
-          res.end();
-        });
-  }
-
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
-
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
-    }
-
-    nlohmann::json patchReq;
-
-    if (!json_util::processJsonFromRequest(res, req, patchReq)) {
-      return;
-    }
-
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId, patchReq = std::move(patchReq) ](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (!success) {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object,
-            // and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
+                messages::resourceNotFound("VLAN Network Interface", iface));
             res.result(boost::beast::http::status::not_found);
             res.end();
 
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // TODO(Pawel) this shall be parametrized call (two params) to get
+        // EthernetInterfaces for any Manager, not only hardcoded 'openbmc'.
+        // Check if there is required param, truly entering this shall be
+        // impossible.
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
             return;
-          }
+        }
 
-          res.jsonValue =
-              parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
 
-          std::shared_ptr<AsyncResp> asyncResp =
-              std::make_shared<AsyncResp>(res);
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
 
-          for (auto propertyIt = patchReq.begin(); propertyIt != patchReq.end();
-               ++propertyIt) {
-            if (propertyIt.key() != "VLANEnable" &&
-                propertyIt.key() != "VLANId") {
-              auto fieldInJsonIt = res.jsonValue.find(propertyIt.key());
-
-              if (fieldInJsonIt == res.jsonValue.end()) {
-                // Field not in scope of defined fields
-                messages::addMessageToJsonRoot(
-                    res.jsonValue, messages::propertyUnknown(propertyIt.key()));
-              } else if (*fieldInJsonIt != *propertyIt) {
-                // User attempted to modify non-writable field
-                messages::addMessageToJsonRoot(
-                    res.jsonValue,
-                    messages::propertyNotWritable(propertyIt.key()));
-              }
-            }
-          }
-
-          EthernetInterface::handleVlanPatch(ifaceId, patchReq, eth_data, "/",
-                                             asyncResp);
-        });
-  }
-
-  void doDelete(crow::Response &res, const crow::Request &req,
-                const std::vector<std::string> &params) override {
-    if (params.size() != 2) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId, [&, parentIfaceId,
+                      ifaceId](const bool &success,
+                               const EthernetInterfaceData &eth_data,
+                               const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success && eth_data.vlanId != nullptr)
+                {
+                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                       eth_data, ipv4_data);
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                }
+                res.end();
+            });
     }
 
-    const std::string &parentIfaceId = params[0];
-    const std::string &ifaceId = params[1];
-
-    if (!verifyNames(res, parentIfaceId, ifaceId)) {
-      return;
-    }
-
-    // Get single eth interface data, and call the below callback for JSON
-    // preparation
-    ethernetProvider.getEthernetIfaceData(
-        ifaceId, [&, parentIfaceId, ifaceId](
-                     const bool &success, const EthernetInterfaceData &eth_data,
-                     const std::vector<IPv4AddressData> &ipv4_data) {
-          if (success && eth_data.vlanId != nullptr) {
-            res.jsonValue =
-                parseInterfaceData(parentIfaceId, ifaceId, eth_data, ipv4_data);
-
-            // Disable VLAN
-            OnDemandEthernetProvider::disableVlan(
-                ifaceId, [&](const boost::system::error_code ec) {
-                  if (ec) {
-                    res.jsonValue = nlohmann::json::object();
-                    messages::addMessageToErrorJson(res.jsonValue,
-                                                    messages::internalError());
-                    res.result(
-                        boost::beast::http::status::internal_server_error);
-                  }
-                  res.end();
-                });
-          } else {
-            // ... otherwise return error
-            // TODO(Pawel)consider distinguish between non existing object,
-            // and
-            // other errors
-            messages::addMessageToErrorJson(
-                res.jsonValue,
-                messages::resourceNotFound("VLAN Network Interface", ifaceId));
-            res.result(boost::beast::http::status::not_found);
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
             res.end();
-          }
-        });
-  }
+            return;
+        }
 
-  /**
-   * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
-   * method, to maintain consistency of returned data, as Collection's doPost
-   * should return data for created member which should match member's doGet
-   * result in 100%.
-   */
-  friend VlanNetworkInterfaceCollection;
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
+
+        nlohmann::json patchReq;
+
+        if (!json_util::processJsonFromRequest(res, req, patchReq))
+        {
+            return;
+        }
+
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId,
+            [&, parentIfaceId, ifaceId, patchReq = std::move(patchReq)](
+                const bool &success, const EthernetInterfaceData &eth_data,
+                const std::vector<IPv4AddressData> &ipv4_data) {
+                if (!success)
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+
+                    return;
+                }
+
+                res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                   eth_data, ipv4_data);
+
+                std::shared_ptr<AsyncResp> asyncResp =
+                    std::make_shared<AsyncResp>(res);
+
+                for (auto propertyIt = patchReq.begin();
+                     propertyIt != patchReq.end(); ++propertyIt)
+                {
+                    if (propertyIt.key() != "VLANEnable" &&
+                        propertyIt.key() != "VLANId")
+                    {
+                        auto fieldInJsonIt =
+                            res.jsonValue.find(propertyIt.key());
+
+                        if (fieldInJsonIt == res.jsonValue.end())
+                        {
+                            // Field not in scope of defined fields
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue,
+                                messages::propertyUnknown(propertyIt.key()));
+                        }
+                        else if (*fieldInJsonIt != *propertyIt)
+                        {
+                            // User attempted to modify non-writable field
+                            messages::addMessageToJsonRoot(
+                                res.jsonValue, messages::propertyNotWritable(
+                                                   propertyIt.key()));
+                        }
+                    }
+                }
+
+                EthernetInterface::handleVlanPatch(ifaceId, patchReq, eth_data,
+                                                   "/", asyncResp);
+            });
+    }
+
+    void doDelete(crow::Response &res, const crow::Request &req,
+                  const std::vector<std::string> &params) override
+    {
+        if (params.size() != 2)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        const std::string &parentIfaceId = params[0];
+        const std::string &ifaceId = params[1];
+
+        if (!verifyNames(res, parentIfaceId, ifaceId))
+        {
+            return;
+        }
+
+        // Get single eth interface data, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceData(
+            ifaceId, [&, parentIfaceId,
+                      ifaceId](const bool &success,
+                               const EthernetInterfaceData &eth_data,
+                               const std::vector<IPv4AddressData> &ipv4_data) {
+                if (success && eth_data.vlanId != nullptr)
+                {
+                    res.jsonValue = parseInterfaceData(parentIfaceId, ifaceId,
+                                                       eth_data, ipv4_data);
+
+                    // Disable VLAN
+                    OnDemandEthernetProvider::disableVlan(
+                        ifaceId, [&](const boost::system::error_code ec) {
+                            if (ec)
+                            {
+                                res.jsonValue = nlohmann::json::object();
+                                messages::addMessageToErrorJson(
+                                    res.jsonValue, messages::internalError());
+                                res.result(boost::beast::http::status::
+                                               internal_server_error);
+                            }
+                            res.end();
+                        });
+                }
+                else
+                {
+                    // ... otherwise return error
+                    // TODO(Pawel)consider distinguish between non existing
+                    // object, and other errors
+                    messages::addMessageToErrorJson(
+                        res.jsonValue, messages::resourceNotFound(
+                                           "VLAN Network Interface", ifaceId));
+                    res.result(boost::beast::http::status::not_found);
+                    res.end();
+                }
+            });
+    }
+
+    /**
+     * This allows VlanNetworkInterfaceCollection to reuse this class' doGet
+     * method, to maintain consistency of returned data, as Collection's doPost
+     * should return data for created member which should match member's doGet
+     * result in 100%.
+     */
+    friend VlanNetworkInterfaceCollection;
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
 };
 
 /**
  * VlanNetworkInterfaceCollection derived class for delivering
  * VLANNetworkInterface Collection Schema
  */
-class VlanNetworkInterfaceCollection : public Node {
- public:
-  template <typename CrowApp>
-  // TODO(Pawel) Remove line from below, where we assume that there is only one
-  // manager called openbmc This shall be generic, but requires to update
-  // GetSubroutes method
-  VlanNetworkInterfaceCollection(CrowApp &app)
-      : Node(app,
+class VlanNetworkInterfaceCollection : public Node
+{
+  public:
+    template <typename CrowApp>
+    // TODO(Pawel) Remove line from below, where we assume that there is only
+    // one manager called openbmc This shall be generic, but requires to update
+    // GetSubroutes method
+    VlanNetworkInterfaceCollection(CrowApp &app) :
+        Node(app,
              "/redfish/v1/Managers/openbmc/EthernetInterfaces/<str>/VLANs/",
              std::string()),
-        memberVlan(app) {
-    Node::json["@odata.type"] =
-        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata"
-        "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
-    Node::json["Name"] = "VLAN Network Interface Collection";
+        memberVlan(app)
+    {
+        Node::json["@odata.type"] =
+            "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata"
+            "#VLanNetworkInterfaceCollection.VLanNetworkInterfaceCollection";
+        Node::json["Name"] = "VLAN Network Interface Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    if (params.size() != 1) {
-      // This means there is a problem with the router
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-    std::string rootInterfaceName = params[0];
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        if (params.size() != 1)
+        {
+            // This means there is a problem with the router
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
 
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([
-          &, managerId{std::move(managerId)},
-          rootInterfaceName{std::move(rootInterfaceName)}
-    ](const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        bool rootInterfaceFound = false;
-        nlohmann::json ifaceArray = nlohmann::json::array();
-
-        for (const std::string &ifaceItem : iface_list) {
-          if (ifaceItem == rootInterfaceName) {
-            rootInterfaceFound = true;
-          } else if (boost::starts_with(ifaceItem, rootInterfaceName + "_")) {
-            ifaceArray.push_back(
-                {{"@odata.id", "/redfish/v1/Managers/" + managerId +
-                                   "/EthernetInterfaces/" + rootInterfaceName +
-                                   "/VLANs/" + ifaceItem}});
-          }
+            return;
         }
 
-        if (rootInterfaceFound) {
-          Node::json["Members"] = ifaceArray;
-          Node::json["Members@odata.count"] = ifaceArray.size();
-          Node::json["@odata.id"] = "/redfish/v1/Managers/" + managerId +
-                                    "/EthernetInterfaces/" + rootInterfaceName +
-                                    "/VLANs";
-          res.jsonValue = Node::json;
-        } else {
-          messages::addMessageToErrorJson(
-              res.jsonValue, messages::resourceNotFound("EthernetInterface",
-                                                        rootInterfaceName));
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-        }
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-      }
-      res.end();
-    });
-  }
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+        std::string rootInterfaceName = params[0];
 
-  void doPost(crow::Response &res, const crow::Request &req,
-              const std::vector<std::string> &params) override {
-    if (params.size() != 1) {
-      // This means there is a problem with the router
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)},
+             rootInterfaceName{std::move(rootInterfaceName)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    bool rootInterfaceFound = false;
+                    nlohmann::json ifaceArray = nlohmann::json::array();
 
-    nlohmann::json postReq;
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        if (ifaceItem == rootInterfaceName)
+                        {
+                            rootInterfaceFound = true;
+                        }
+                        else if (boost::starts_with(ifaceItem,
+                                                    rootInterfaceName + "_"))
+                        {
+                            ifaceArray.push_back(
+                                {{"@odata.id", "/redfish/v1/Managers/" +
+                                                   managerId +
+                                                   "/EthernetInterfaces/" +
+                                                   rootInterfaceName +
+                                                   "/VLANs/" + ifaceItem}});
+                        }
+                    }
 
-    if (!json_util::processJsonFromRequest(res, req, postReq)) {
-      return;
-    }
-
-    // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces for
-    // any Manager, not only hardcoded 'openbmc'.
-    std::string managerId = "openbmc";
-    std::string rootInterfaceName = params[0];
-    uint64_t vlanId;
-    bool errorDetected;
-
-    if (json_util::getUnsigned(
-            "VLANId", postReq, vlanId,
-            static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
-                static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
-            res.jsonValue, "/VLANId") != json_util::Result::SUCCESS) {
-      res.end();
-      return;
-    }
-
-    // get eth interface list, and call the below callback for JSON preparation
-    ethernetProvider.getEthernetIfaceList([
-          &, managerId{std::move(managerId)},
-          rootInterfaceName{std::move(rootInterfaceName)}
-    ](const bool &success, const std::vector<std::string> &iface_list) {
-      if (success) {
-        bool rootInterfaceFound = false;
-
-        for (const std::string &ifaceItem : iface_list) {
-          if (ifaceItem == rootInterfaceName) {
-            rootInterfaceFound = true;
-            break;
-          }
-        }
-
-        if (rootInterfaceFound) {
-          ethernetProvider.createVlan(
-              rootInterfaceName, vlanId,
-              [&, vlanId, rootInterfaceName,
-               req{std::move(req)} ](const boost::system::error_code ec) {
-                if (ec) {
-                  messages::addMessageToErrorJson(res.jsonValue,
-                                                  messages::internalError());
-                  res.end();
-                } else {
-                  memberVlan.doGet(
-                      res, req,
-                      {rootInterfaceName,
-                       rootInterfaceName + "_" + std::to_string(vlanId)});
+                    if (rootInterfaceFound)
+                    {
+                        Node::json["Members"] = ifaceArray;
+                        Node::json["Members@odata.count"] = ifaceArray.size();
+                        Node::json["@odata.id"] = "/redfish/v1/Managers/" +
+                                                  managerId +
+                                                  "/EthernetInterfaces/" +
+                                                  rootInterfaceName + "/VLANs";
+                        res.jsonValue = Node::json;
+                    }
+                    else
+                    {
+                        messages::addMessageToErrorJson(
+                            res.jsonValue,
+                            messages::resourceNotFound("EthernetInterface",
+                                                       rootInterfaceName));
+                        res.result(boost::beast::http::status::not_found);
+                        res.end();
+                    }
                 }
-              });
-        } else {
-          messages::addMessageToErrorJson(
-              res.jsonValue, messages::resourceNotFound("EthernetInterface",
-                                                        rootInterfaceName));
-          res.result(boost::beast::http::status::not_found);
-          res.end();
-        }
-      } else {
-        // No success, best what we can do is return INTERNALL ERROR
-        res.result(boost::beast::http::status::internal_server_error);
-        res.end();
-      }
-    });
-  }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                }
+                res.end();
+            });
+    }
 
-  // Ethernet Provider object
-  // TODO(Pawel) consider move it to singleton
-  OnDemandEthernetProvider ethernetProvider;
-  VlanNetworkInterface memberVlan;
+    void doPost(crow::Response &res, const crow::Request &req,
+                const std::vector<std::string> &params) override
+    {
+        if (params.size() != 1)
+        {
+            // This means there is a problem with the router
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+
+        nlohmann::json postReq;
+
+        if (!json_util::processJsonFromRequest(res, req, postReq))
+        {
+            return;
+        }
+
+        // TODO(Pawel) this shall be parametrized call to get EthernetInterfaces
+        // for any Manager, not only hardcoded 'openbmc'.
+        std::string managerId = "openbmc";
+        std::string rootInterfaceName = params[0];
+        uint64_t vlanId;
+        bool errorDetected;
+
+        if (json_util::getUnsigned(
+                "VLANId", postReq, vlanId,
+                static_cast<uint8_t>(json_util::MessageSetting::MISSING) |
+                    static_cast<uint8_t>(json_util::MessageSetting::TYPE_ERROR),
+                res.jsonValue, "/VLANId") != json_util::Result::SUCCESS)
+        {
+            res.end();
+            return;
+        }
+
+        // get eth interface list, and call the below callback for JSON
+        // preparation
+        ethernetProvider.getEthernetIfaceList(
+            [&, managerId{std::move(managerId)},
+             rootInterfaceName{std::move(rootInterfaceName)}](
+                const bool &success,
+                const std::vector<std::string> &iface_list) {
+                if (success)
+                {
+                    bool rootInterfaceFound = false;
+
+                    for (const std::string &ifaceItem : iface_list)
+                    {
+                        if (ifaceItem == rootInterfaceName)
+                        {
+                            rootInterfaceFound = true;
+                            break;
+                        }
+                    }
+
+                    if (rootInterfaceFound)
+                    {
+                        ethernetProvider.createVlan(
+                            rootInterfaceName, vlanId,
+                            [&, vlanId, rootInterfaceName, req{std::move(req)}](
+                                const boost::system::error_code ec) {
+                                if (ec)
+                                {
+                                    messages::addMessageToErrorJson(
+                                        res.jsonValue,
+                                        messages::internalError());
+                                    res.end();
+                                }
+                                else
+                                {
+                                    memberVlan.doGet(
+                                        res, req,
+                                        {rootInterfaceName,
+                                         rootInterfaceName + "_" +
+                                             std::to_string(vlanId)});
+                                }
+                            });
+                    }
+                    else
+                    {
+                        messages::addMessageToErrorJson(
+                            res.jsonValue,
+                            messages::resourceNotFound("EthernetInterface",
+                                                       rootInterfaceName));
+                        res.result(boost::beast::http::status::not_found);
+                        res.end();
+                    }
+                }
+                else
+                {
+                    // No success, best what we can do is return INTERNALL ERROR
+                    res.result(
+                        boost::beast::http::status::internal_server_error);
+                    res.end();
+                }
+            });
+    }
+
+    // Ethernet Provider object
+    // TODO(Pawel) consider move it to singleton
+    OnDemandEthernetProvider ethernetProvider;
+    VlanNetworkInterface memberVlan;
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 7a861b4..86fe567 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -17,101 +17,111 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Manager : public Node {
- public:
-  Manager(CrowApp& app) : Node(app, "/redfish/v1/Managers/openbmc/") {
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc";
-    Node::json["@odata.type"] = "#Manager.v1_3_0.Manager";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager";
-    Node::json["Id"] = "openbmc";
-    Node::json["Name"] = "OpenBmc Manager";
-    Node::json["Description"] = "Baseboard Management Controller";
-    Node::json["PowerState"] = "On";
-    Node::json["UUID"] =
-        app.template getMiddleware<crow::persistent_data::Middleware>()
-            .systemUuid;
-    Node::json["Model"] = "OpenBmc";               // TODO(ed), get model
-    Node::json["FirmwareVersion"] = "1234456789";  // TODO(ed), get fwversion
-    Node::json["EthernetInterfaces"] = nlohmann::json(
-        {{"@odata.id",
-          "/redfish/v1/Managers/openbmc/EthernetInterfaces"}});  // TODO(Pawel),
-                                                                 // remove this
-                                                                 // when
-                                                                 // subroutes
-                                                                 // will work
-                                                                 // correctly
+class Manager : public Node
+{
+  public:
+    Manager(CrowApp& app) : Node(app, "/redfish/v1/Managers/openbmc/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc";
+        Node::json["@odata.type"] = "#Manager.v1_3_0.Manager";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Manager.Manager";
+        Node::json["Id"] = "openbmc";
+        Node::json["Name"] = "OpenBmc Manager";
+        Node::json["Description"] = "Baseboard Management Controller";
+        Node::json["PowerState"] = "On";
+        Node::json["UUID"] =
+            app.template getMiddleware<crow::persistent_data::Middleware>()
+                .systemUuid;
+        Node::json["Model"] = "OpenBmc";              // TODO(ed), get model
+        Node::json["FirmwareVersion"] = "1234456789"; // TODO(ed), get fwversion
+        Node::json["EthernetInterfaces"] = nlohmann::json(
+            {{"@odata.id", "/redfish/v1/Managers/openbmc/"
+                           "EthernetInterfaces"}}); // TODO(Pawel),
+                                                    // remove this
+                                                    // when
+                                                    // subroutes
+                                                    // will work
+                                                    // correctly
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    Node::json["DateTime"] = getDateTime();
-    // Copy over the static data to include the entries added by SubRoute
-    res.jsonValue = Node::json;
-    res.end();
-  }
-
-  std::string getDateTime() const {
-    std::array<char, 128> dateTime;
-    std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
-    std::time_t time = std::time(nullptr);
-
-    if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
-                      std::localtime(&time))) {
-      // insert the colon required by the ISO 8601 standard
-      redfishDateTime = std::string(dateTime.data());
-      redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    return redfishDateTime;
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        Node::json["DateTime"] = getDateTime();
+        // Copy over the static data to include the entries added by SubRoute
+        res.jsonValue = Node::json;
+        res.end();
+    }
+
+    std::string getDateTime() const
+    {
+        std::array<char, 128> dateTime;
+        std::string redfishDateTime("0000-00-00T00:00:00Z00:00");
+        std::time_t time = std::time(nullptr);
+
+        if (std::strftime(dateTime.begin(), dateTime.size(), "%FT%T%z",
+                          std::localtime(&time)))
+        {
+            // insert the colon required by the ISO 8601 standard
+            redfishDateTime = std::string(dateTime.data());
+            redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+        }
+
+        return redfishDateTime;
+    }
 };
 
-class ManagerCollection : public Node {
- public:
-  ManagerCollection(CrowApp& app) : Node(app, "/redfish/v1/Managers/") {
-    Node::json["@odata.id"] = "/redfish/v1/Managers";
-    Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
-    Node::json["Name"] = "Manager Collection";
-    Node::json["Members@odata.count"] = 1;
-    Node::json["Members"] = {{{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+class ManagerCollection : public Node
+{
+  public:
+    ManagerCollection(CrowApp& app) : Node(app, "/redfish/v1/Managers/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/Managers";
+        Node::json["@odata.type"] = "#ManagerCollection.ManagerCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
+        Node::json["Name"] = "Manager Collection";
+        Node::json["Members@odata.count"] = 1;
+        Node::json["Members"] = {
+            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    // Collections don't include the static data added by SubRoute because it
-    // has a duplicate entry for members
-    res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
-    res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection";
-    res.jsonValue["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
-    res.jsonValue["Name"] = "Manager Collection";
-    res.jsonValue["Members@odata.count"] = 1;
-    res.jsonValue["Members"] = {
-        {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        // Collections don't include the static data added by SubRoute because
+        // it has a duplicate entry for members
+        res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
+        res.jsonValue["@odata.type"] = "#ManagerCollection.ManagerCollection";
+        res.jsonValue["@odata.context"] =
+            "/redfish/v1/$metadata#ManagerCollection.ManagerCollection";
+        res.jsonValue["Name"] = "Manager Collection";
+        res.jsonValue["Members@odata.count"] = 1;
+        res.jsonValue["Members"] = {
+            {{"@odata.id", "/redfish/v1/Managers/openbmc"}}};
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index ae29df0..bb021f5 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -18,24 +18,27 @@
 #include "error_messages.hpp"
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-enum NetworkProtocolUnitStructFields {
-  NET_PROTO_UNIT_NAME,
-  NET_PROTO_UNIT_DESC,
-  NET_PROTO_UNIT_LOAD_STATE,
-  NET_PROTO_UNIT_ACTIVE_STATE,
-  NET_PROTO_UNIT_SUB_STATE,
-  NET_PROTO_UNIT_DEVICE,
-  NET_PROTO_UNIT_OBJ_PATH,
-  NET_PROTO_UNIT_ALWAYS_0,
-  NET_PROTO_UNIT_ALWAYS_EMPTY,
-  NET_PROTO_UNIT_ALWAYS_ROOT_PATH
+enum NetworkProtocolUnitStructFields
+{
+    NET_PROTO_UNIT_NAME,
+    NET_PROTO_UNIT_DESC,
+    NET_PROTO_UNIT_LOAD_STATE,
+    NET_PROTO_UNIT_ACTIVE_STATE,
+    NET_PROTO_UNIT_SUB_STATE,
+    NET_PROTO_UNIT_DEVICE,
+    NET_PROTO_UNIT_OBJ_PATH,
+    NET_PROTO_UNIT_ALWAYS_0,
+    NET_PROTO_UNIT_ALWAYS_EMPTY,
+    NET_PROTO_UNIT_ALWAYS_ROOT_PATH
 };
 
-enum NetworkProtocolListenResponseElements {
-  NET_PROTO_LISTEN_TYPE,
-  NET_PROTO_LISTEN_STREAM
+enum NetworkProtocolListenResponseElements
+{
+    NET_PROTO_LISTEN_TYPE,
+    NET_PROTO_LISTEN_STREAM
 };
 
 /**
@@ -46,9 +49,10 @@
                std::string, sdbusplus::message::object_path, uint32_t,
                std::string, sdbusplus::message::object_path>;
 
-struct ServiceConfiguration {
-  const char* serviceName;
-  const char* socketPath;
+struct ServiceConfiguration
+{
+    const char* serviceName;
+    const char* socketPath;
 };
 
 const static boost::container::flat_map<const char*, ServiceConfiguration>
@@ -63,128 +67,161 @@
          {"phosphor-ipmi-net.service",
           "/org/freedesktop/systemd1/unit/phosphor_2dipmi_2dnet_2esocket"}}};
 
-class NetworkProtocol : public Node {
- public:
-  NetworkProtocol(CrowApp& app)
-      : Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol") {
-    Node::json["@odata.type"] =
-        "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
-    Node::json["@odata.id"] = "/redfish/v1/Managers/openbmc/NetworkProtocol";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
-    Node::json["Id"] = "NetworkProtocol";
-    Node::json["Name"] = "Manager Network Protocol";
-    Node::json["Description"] = "Manager Network Service";
-    Node::json["Status"]["Health"] = "OK";
-    Node::json["Status"]["HealthRollup"] = "OK";
-    Node::json["Status"]["State"] = "Enabled";
+class NetworkProtocol : public Node
+{
+  public:
+    NetworkProtocol(CrowApp& app) :
+        Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol")
+    {
+        Node::json["@odata.type"] =
+            "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol";
+        Node::json["@odata.id"] =
+            "/redfish/v1/Managers/openbmc/NetworkProtocol";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol";
+        Node::json["Id"] = "NetworkProtocol";
+        Node::json["Name"] = "Manager Network Protocol";
+        Node::json["Description"] = "Manager Network Service";
+        Node::json["Status"]["Health"] = "OK";
+        Node::json["Status"]["HealthRollup"] = "OK";
+        Node::json["Status"]["State"] = "Enabled";
 
-    for (auto& protocol : protocolToDBus) {
-      Node::json[protocol.first]["ProtocolEnabled"] = false;
+        for (auto& protocol : protocolToDBus)
+        {
+            Node::json[protocol.first]["ProtocolEnabled"] = false;
+        }
+
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-
-    getData(asyncResp);
-  }
-
-  std::string getHostName() const {
-    std::string hostName;
-
-    std::array<char, HOST_NAME_MAX> hostNameCStr;
-    if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) {
-      hostName = hostNameCStr.data();
+        getData(asyncResp);
     }
-    return hostName;
-  }
 
-  void getData(const std::shared_ptr<AsyncResp>& asyncResp) {
-    Node::json["HostName"] = getHostName();
-    asyncResp->res.jsonValue = Node::json;
+    std::string getHostName() const
+    {
+        std::string hostName;
 
-    crow::connections::systemBus->async_method_call(
-        [asyncResp](const boost::system::error_code ec,
-                    const std::vector<UnitStruct>& resp) {
-          if (ec) {
-            asyncResp->res.jsonValue = nlohmann::json::object();
-            messages::addMessageToErrorJson(asyncResp->res.jsonValue,
-                                            messages::internalError());
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return;
-          }
+        std::array<char, HOST_NAME_MAX> hostNameCStr;
+        if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
+        {
+            hostName = hostNameCStr.data();
+        }
+        return hostName;
+    }
 
-          for (auto& unit : resp) {
-            for (auto& kv : protocolToDBus) {
-              if (kv.second.serviceName ==
-                  std::get<NET_PROTO_UNIT_NAME>(unit)) {
-                continue;
-              }
-              const char* service = kv.first;
-              const char* socketPath = kv.second.socketPath;
+    void getData(const std::shared_ptr<AsyncResp>& asyncResp)
+    {
+        Node::json["HostName"] = getHostName();
+        asyncResp->res.jsonValue = Node::json;
 
-              asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
-                  std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == "running";
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](const boost::system::error_code ec,
+                        const std::vector<UnitStruct>& resp) {
+                if (ec)
+                {
+                    asyncResp->res.jsonValue = nlohmann::json::object();
+                    messages::addMessageToErrorJson(asyncResp->res.jsonValue,
+                                                    messages::internalError());
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
 
-              crow::connections::systemBus->async_method_call(
-                  [ asyncResp, service{std::string(service)}, socketPath ](
-                      const boost::system::error_code ec,
-                      const sdbusplus::message::variant<std::vector<
-                          std::tuple<std::string, std::string>>>& resp) {
-                    if (ec) {
-                      messages::addMessageToJson(asyncResp->res.jsonValue,
-                                                 messages::internalError(),
-                                                 "/" + service);
-                      return;
+                for (auto& unit : resp)
+                {
+                    for (auto& kv : protocolToDBus)
+                    {
+                        if (kv.second.serviceName ==
+                            std::get<NET_PROTO_UNIT_NAME>(unit))
+                        {
+                            continue;
+                        }
+                        const char* service = kv.first;
+                        const char* socketPath = kv.second.socketPath;
+
+                        asyncResp->res.jsonValue[service]["ProtocolEnabled"] =
+                            std::get<NET_PROTO_UNIT_SUB_STATE>(unit) ==
+                            "running";
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp, service{std::string(service)},
+                             socketPath](
+                                const boost::system::error_code ec,
+                                const sdbusplus::message::variant<std::vector<
+                                    std::tuple<std::string, std::string>>>&
+                                    resp) {
+                                if (ec)
+                                {
+                                    messages::addMessageToJson(
+                                        asyncResp->res.jsonValue,
+                                        messages::internalError(),
+                                        "/" + service);
+                                    return;
+                                }
+                                const std::vector<std::tuple<
+                                    std::string, std::string>>* responsePtr =
+                                    mapbox::getPtr<const std::vector<
+                                        std::tuple<std::string, std::string>>>(
+                                        resp);
+                                if (responsePtr == nullptr ||
+                                    responsePtr->size() < 1)
+                                {
+                                    return;
+                                }
+
+                                const std::string& listenStream =
+                                    std::get<NET_PROTO_LISTEN_STREAM>(
+                                        (*responsePtr)[0]);
+                                std::size_t lastColonPos =
+                                    listenStream.rfind(":");
+                                if (lastColonPos == std::string::npos)
+                                {
+                                    // Not a port
+                                    return;
+                                }
+                                std::string portStr =
+                                    listenStream.substr(lastColonPos + 1);
+                                char* endPtr = nullptr;
+                                // Use strtol instead of stroi to avoid
+                                // exceptions
+                                long port =
+                                    std::strtol(portStr.c_str(), &endPtr, 10);
+
+                                if (*endPtr != '\0' || portStr.empty())
+                                {
+                                    // Invalid value
+                                    asyncResp->res.jsonValue[service]["Port"] =
+                                        nullptr;
+                                }
+                                else
+                                {
+                                    // Everything OK
+                                    asyncResp->res.jsonValue[service]["Port"] =
+                                        port;
+                                }
+                            },
+                            "org.freedesktop.systemd1", socketPath,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "org.freedesktop.systemd1.Socket", "Listen");
                     }
-                    const std::vector<std::tuple<std::string, std::string>>*
-                        responsePtr = mapbox::getPtr<const std::vector<
-                            std::tuple<std::string, std::string>>>(resp);
-                    if (responsePtr == nullptr || responsePtr->size() < 1) {
-                      return;
-                    }
-
-                    const std::string& listenStream =
-                        std::get<NET_PROTO_LISTEN_STREAM>((*responsePtr)[0]);
-                    std::size_t lastColonPos = listenStream.rfind(":");
-                    if (lastColonPos == std::string::npos) {
-                      // Not a port
-                      return;
-                    }
-                    std::string portStr = listenStream.substr(lastColonPos + 1);
-                    char* endPtr = nullptr;
-                    // Use strtol instead of stroi to avoid exceptions
-                    long port = std::strtol(portStr.c_str(), &endPtr, 10);
-
-                    if (*endPtr != '\0' || portStr.empty()) {
-                      // Invalid value
-                      asyncResp->res.jsonValue[service]["Port"] = nullptr;
-                    } else {
-                      // Everything OK
-                      asyncResp->res.jsonValue[service]["Port"] = port;
-                    }
-                  },
-                  "org.freedesktop.systemd1", socketPath,
-                  "org.freedesktop.DBus.Properties", "Get",
-                  "org.freedesktop.systemd1.Socket", "Listen");
-            }
-          }
-        },
-        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
-        "org.freedesktop.systemd1.Manager", "ListUnits");
-  }
+                }
+            },
+            "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+            "org.freedesktop.systemd1.Manager", "ListUnits");
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index ca1c375..2406250 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -19,312 +19,348 @@
 #include "node.hpp"
 #include "persistent_data_middleware.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
 class SessionCollection;
 
-class Sessions : public Node {
- public:
-  Sessions(CrowApp& app)
-      : Node(app, "/redfish/v1/SessionService/Sessions/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#Session.v1_0_2.Session";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
-    Node::json["Name"] = "User Session";
-    Node::json["Description"] = "Manager User Session";
+class Sessions : public Node
+{
+  public:
+    Sessions(CrowApp& app) :
+        Node(app, "/redfish/v1/SessionService/Sessions/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#Session.v1_0_2.Session";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Session.Session";
+        Node::json["Name"] = "User Session";
+        Node::json["Description"] = "Manager User Session";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().getSessionByUid(
-            params[0]);
-
-    if (session == nullptr) {
-      messages::addMessageToErrorJson(
-          res.jsonValue, messages::resourceNotFound("Session", params[0]));
-
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
 
-    Node::json["Id"] = session->uniqueId;
-    Node::json["UserName"] = session->username;
-    Node::json["@odata.id"] =
-        "/redfish/v1/SessionService/Sessions/" + session->uniqueId;
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        auto session =
+            crow::persistent_data::SessionStore::getInstance().getSessionByUid(
+                params[0]);
 
-    res.jsonValue = Node::json;
-    res.end();
-  }
+        if (session == nullptr)
+        {
+            messages::addMessageToErrorJson(
+                res.jsonValue,
+                messages::resourceNotFound("Session", params[0]));
 
-  void doDelete(crow::Response& res, const crow::Request& req,
-                const std::vector<std::string>& params) override {
-    // Need only 1 param which should be id of session to be deleted
-    if (params.size() != 1) {
-      // This should be handled by crow and never happen
-      BMCWEB_LOG_ERROR
-          << "Session DELETE has been called with invalid number of params";
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
 
-      res.result(boost::beast::http::status::bad_request);
-      messages::addMessageToErrorJson(res.jsonValue, messages::generalError());
+        Node::json["Id"] = session->uniqueId;
+        Node::json["UserName"] = session->username;
+        Node::json["@odata.id"] =
+            "/redfish/v1/SessionService/Sessions/" + session->uniqueId;
 
-      res.end();
-      return;
+        res.jsonValue = Node::json;
+        res.end();
     }
 
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().getSessionByUid(
-            params[0]);
+    void doDelete(crow::Response& res, const crow::Request& req,
+                  const std::vector<std::string>& params) override
+    {
+        // Need only 1 param which should be id of session to be deleted
+        if (params.size() != 1)
+        {
+            // This should be handled by crow and never happen
+            BMCWEB_LOG_ERROR << "Session DELETE has been called with invalid "
+                                "number of params";
 
-    if (session == nullptr) {
-      messages::addMessageToErrorJson(
-          res.jsonValue, messages::resourceNotFound("Session", params[0]));
+            res.result(boost::beast::http::status::bad_request);
+            messages::addMessageToErrorJson(res.jsonValue,
+                                            messages::generalError());
 
-      res.result(boost::beast::http::status::not_found);
-      res.end();
-      return;
+            res.end();
+            return;
+        }
+
+        auto session =
+            crow::persistent_data::SessionStore::getInstance().getSessionByUid(
+                params[0]);
+
+        if (session == nullptr)
+        {
+            messages::addMessageToErrorJson(
+                res.jsonValue,
+                messages::resourceNotFound("Session", params[0]));
+
+            res.result(boost::beast::http::status::not_found);
+            res.end();
+            return;
+        }
+
+        // DELETE should return representation of object that will be removed
+        doGet(res, req, params);
+
+        crow::persistent_data::SessionStore::getInstance().removeSession(
+            session);
     }
 
-    // DELETE should return representation of object that will be removed
-    doGet(res, req, params);
-
-    crow::persistent_data::SessionStore::getInstance().removeSession(session);
-  }
-
-  /**
-   * This allows SessionCollection to reuse this class' doGet method, to
-   * maintain consistency of returned data, as Collection's doPost should return
-   * data for created member which should match member's doGet result in 100%
-   */
-  friend SessionCollection;
+    /**
+     * This allows SessionCollection to reuse this class' doGet method, to
+     * maintain consistency of returned data, as Collection's doPost should
+     * return data for created member which should match member's doGet result
+     * in 100%
+     */
+    friend SessionCollection;
 };
 
-class SessionCollection : public Node {
- public:
-  SessionCollection(CrowApp& app)
-      : Node(app, "/redfish/v1/SessionService/Sessions/"), memberSession(app) {
-    Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
-    Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SessionCollection.SessionCollection";
-    Node::json["Name"] = "Session Collection";
-    Node::json["Description"] = "Session Collection";
-    Node::json["Members@odata.count"] = 0;
-    Node::json["Members"] = nlohmann::json::array();
+class SessionCollection : public Node
+{
+  public:
+    SessionCollection(CrowApp& app) :
+        Node(app, "/redfish/v1/SessionService/Sessions/"), memberSession(app)
+    {
+        Node::json["@odata.type"] = "#SessionCollection.SessionCollection";
+        Node::json["@odata.id"] = "/redfish/v1/SessionService/Sessions/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SessionCollection.SessionCollection";
+        Node::json["Name"] = "Session Collection";
+        Node::json["Description"] = "Session Collection";
+        Node::json["Members@odata.count"] = 0;
+        Node::json["Members"] = nlohmann::json::array();
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    std::vector<const std::string*> sessionIds =
-        crow::persistent_data::SessionStore::getInstance().getUniqueIds(
-            false, crow::persistent_data::PersistenceType::TIMEOUT);
-
-    Node::json["Members@odata.count"] = sessionIds.size();
-    Node::json["Members"] = nlohmann::json::array();
-    for (const std::string* uid : sessionIds) {
-      Node::json["Members"].push_back(
-          {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {}}};
     }
 
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        std::vector<const std::string*> sessionIds =
+            crow::persistent_data::SessionStore::getInstance().getUniqueIds(
+                false, crow::persistent_data::PersistenceType::TIMEOUT);
 
-  void doPost(crow::Response& res, const crow::Request& req,
-              const std::vector<std::string>& params) override {
-    boost::beast::http::status status;
-    std::string username;
-    bool userAuthSuccessful =
-        authenticateUser(req, status, username, res.jsonValue);
-    res.result(status);
+        Node::json["Members@odata.count"] = sessionIds.size();
+        Node::json["Members"] = nlohmann::json::array();
+        for (const std::string* uid : sessionIds)
+        {
+            Node::json["Members"].push_back(
+                {{"@odata.id", "/redfish/v1/SessionService/Sessions/" + *uid}});
+        }
 
-    if (!userAuthSuccessful) {
-      res.end();
-      return;
+        res.jsonValue = Node::json;
+        res.end();
     }
 
-    // User is authenticated - create session for him
-    auto session =
-        crow::persistent_data::SessionStore::getInstance().generateUserSession(
-            username);
-    res.addHeader("X-Auth-Token", session->sessionToken);
+    void doPost(crow::Response& res, const crow::Request& req,
+                const std::vector<std::string>& params) override
+    {
+        boost::beast::http::status status;
+        std::string username;
+        bool userAuthSuccessful =
+            authenticateUser(req, status, username, res.jsonValue);
+        res.result(status);
 
-    res.addHeader("Location",
-                  "/redfish/v1/SessionService/Sessions/" + session->uniqueId);
+        if (!userAuthSuccessful)
+        {
+            res.end();
+            return;
+        }
 
-    // Return data for created session
-    memberSession.doGet(res, req, {session->uniqueId});
+        // User is authenticated - create session for him
+        auto session = crow::persistent_data::SessionStore::getInstance()
+                           .generateUserSession(username);
+        res.addHeader("X-Auth-Token", session->sessionToken);
 
-    // No need for res.end(), as it is called by doGet()
-  }
+        res.addHeader("Location", "/redfish/v1/SessionService/Sessions/" +
+                                      session->uniqueId);
 
-  /**
-   * @brief Verifies data provided in request and tries to authenticate user
-   *
-   * @param[in]  req            Crow request containing authentication data
-   * @param[out] httpRespCode   HTTP Code that should be returned in response
-   * @param[out] user           Retrieved username - not filled on failure
-   * @param[out] errJson        JSON to which error messages will be written
-   *
-   * @return true if authentication was successful, false otherwise
-   */
-  bool authenticateUser(const crow::Request& req,
-                        boost::beast::http::status& httpRespCode,
-                        std::string& user, nlohmann::json& errJson) {
-    // We need only UserName and Password - nothing more, nothing less
-    static constexpr const unsigned int numberOfRequiredFieldsInReq = 2;
+        // Return data for created session
+        memberSession.doGet(res, req, {session->uniqueId});
 
-    // call with exceptions disabled
-    auto loginCredentials = nlohmann::json::parse(req.body, nullptr, false);
-    if (loginCredentials.is_discarded()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      messages::addMessageToErrorJson(errJson, messages::malformedJSON());
-
-      return false;
+        // No need for res.end(), as it is called by doGet()
     }
 
-    // Check that there are only as many fields as there should be
-    if (loginCredentials.size() != numberOfRequiredFieldsInReq) {
-      httpRespCode = boost::beast::http::status::bad_request;
+    /**
+     * @brief Verifies data provided in request and tries to authenticate user
+     *
+     * @param[in]  req            Crow request containing authentication data
+     * @param[out] httpRespCode   HTTP Code that should be returned in response
+     * @param[out] user           Retrieved username - not filled on failure
+     * @param[out] errJson        JSON to which error messages will be written
+     *
+     * @return true if authentication was successful, false otherwise
+     */
+    bool authenticateUser(const crow::Request& req,
+                          boost::beast::http::status& httpRespCode,
+                          std::string& user, nlohmann::json& errJson)
+    {
+        // We need only UserName and Password - nothing more, nothing less
+        static constexpr const unsigned int numberOfRequiredFieldsInReq = 2;
 
-      messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+        // call with exceptions disabled
+        auto loginCredentials = nlohmann::json::parse(req.body, nullptr, false);
+        if (loginCredentials.is_discarded())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
 
-      return false;
+            messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+
+            return false;
+        }
+
+        // Check that there are only as many fields as there should be
+        if (loginCredentials.size() != numberOfRequiredFieldsInReq)
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            messages::addMessageToErrorJson(errJson, messages::malformedJSON());
+
+            return false;
+        }
+
+        // Find fields that we need - UserName and Password
+        auto userIt = loginCredentials.find("UserName");
+        auto passIt = loginCredentials.find("Password");
+        if (userIt == loginCredentials.end() ||
+            passIt == loginCredentials.end())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (userIt == loginCredentials.end())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("UserName"));
+            }
+
+            if (passIt == loginCredentials.end())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("Password"));
+            }
+
+            return false;
+        }
+
+        // Check that given data is of valid type (string)
+        if (!userIt->is_string() || !passIt->is_string())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (!userIt->is_string())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyValueTypeError(userIt->dump(),
+                                                              "UserName"));
+            }
+
+            if (!passIt->is_string())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyValueTypeError(userIt->dump(),
+                                                              "Password"));
+            }
+
+            return false;
+        }
+
+        // Extract username and password
+        std::string username = userIt->get<const std::string>();
+        std::string password = passIt->get<const std::string>();
+
+        // Verify that required fields are not empty
+        if (username.empty() || password.empty())
+        {
+            httpRespCode = boost::beast::http::status::bad_request;
+
+            if (username.empty())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("UserName"));
+            }
+
+            if (password.empty())
+            {
+                messages::addMessageToErrorJson(
+                    errJson, messages::propertyMissing("Password"));
+            }
+
+            return false;
+        }
+
+        // Finally - try to authenticate user
+        if (!pamAuthenticateUser(username, password))
+        {
+            httpRespCode = boost::beast::http::status::unauthorized;
+
+            messages::addMessageToErrorJson(
+                errJson,
+                messages::resourceAtUriUnauthorized(
+                    std::string(req.url), "Invalid username or password"));
+
+            return false;
+        }
+
+        // User authenticated successfully
+        httpRespCode = boost::beast::http::status::ok;
+        user = username;
+
+        return true;
     }
 
-    // Find fields that we need - UserName and Password
-    auto userIt = loginCredentials.find("UserName");
-    auto passIt = loginCredentials.find("Password");
-    if (userIt == loginCredentials.end() || passIt == loginCredentials.end()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (userIt == loginCredentials.end()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("UserName"));
-      }
-
-      if (passIt == loginCredentials.end()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("Password"));
-      }
-
-      return false;
-    }
-
-    // Check that given data is of valid type (string)
-    if (!userIt->is_string() || !passIt->is_string()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (!userIt->is_string()) {
-        messages::addMessageToErrorJson(
-            errJson,
-            messages::propertyValueTypeError(userIt->dump(), "UserName"));
-      }
-
-      if (!passIt->is_string()) {
-        messages::addMessageToErrorJson(
-            errJson,
-            messages::propertyValueTypeError(userIt->dump(), "Password"));
-      }
-
-      return false;
-    }
-
-    // Extract username and password
-    std::string username = userIt->get<const std::string>();
-    std::string password = passIt->get<const std::string>();
-
-    // Verify that required fields are not empty
-    if (username.empty() || password.empty()) {
-      httpRespCode = boost::beast::http::status::bad_request;
-
-      if (username.empty()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("UserName"));
-      }
-
-      if (password.empty()) {
-        messages::addMessageToErrorJson(errJson,
-                                        messages::propertyMissing("Password"));
-      }
-
-      return false;
-    }
-
-    // Finally - try to authenticate user
-    if (!pamAuthenticateUser(username, password)) {
-      httpRespCode = boost::beast::http::status::unauthorized;
-
-      messages::addMessageToErrorJson(
-          errJson, messages::resourceAtUriUnauthorized(
-                       std::string(req.url), "Invalid username or password"));
-
-      return false;
-    }
-
-    // User authenticated successfully
-    httpRespCode = boost::beast::http::status::ok;
-    user = username;
-
-    return true;
-  }
-
-  /**
-   * Member session to ensure consistency between collection's doPost and
-   * member's doGet, as they should return 100% matching data
-   */
-  Sessions memberSession;
+    /**
+     * Member session to ensure consistency between collection's doPost and
+     * member's doGet, as they should return 100% matching data
+     */
+    Sessions memberSession;
 };
 
-class SessionService : public Node {
- public:
-  SessionService(CrowApp& app) : Node(app, "/redfish/v1/SessionService/") {
-    Node::json["@odata.type"] = "#SessionService.v1_0_2.SessionService";
-    Node::json["@odata.id"] = "/redfish/v1/SessionService/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SessionService.SessionService";
-    Node::json["Name"] = "Session Service";
-    Node::json["Id"] = "SessionService";
-    Node::json["Description"] = "Session Service";
-    Node::json["SessionTimeout"] =
-        crow::persistent_data::SessionStore::getInstance()
-            .getTimeoutInSeconds();
-    Node::json["ServiceEnabled"] = true;
+class SessionService : public Node
+{
+  public:
+    SessionService(CrowApp& app) : Node(app, "/redfish/v1/SessionService/")
+    {
+        Node::json["@odata.type"] = "#SessionService.v1_0_2.SessionService";
+        Node::json["@odata.id"] = "/redfish/v1/SessionService/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SessionService.SessionService";
+        Node::json["Name"] = "Session Service";
+        Node::json["Id"] = "SessionService";
+        Node::json["Description"] = "Session Service";
+        Node::json["SessionTimeout"] =
+            crow::persistent_data::SessionStore::getInstance()
+                .getTimeoutInSeconds();
+        Node::json["ServiceEnabled"] = true;
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/roles.hpp b/redfish-core/lib/roles.hpp
index 72d7948..258eed3 100644
--- a/redfish-core/lib/roles.hpp
+++ b/redfish-core/lib/roles.hpp
@@ -17,74 +17,82 @@
 
 #include "node.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Roles : public Node {
- public:
-  Roles(CrowApp& app)
-      : Node(app, "/redfish/v1/AccountService/Roles/Administrator/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles/Administrator";
-    Node::json["@odata.type"] = "#Role.v1_0_2.Role";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
-    Node::json["Id"] = "Administrator";
-    Node::json["Name"] = "User Role";
-    Node::json["Description"] = "Administrator User Role";
-    Node::json["IsPredefined"] = true;
-    Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
-                                        "ConfigureUsers", "ConfigureSelf",
-                                        "ConfigureComponents"};
-    Node::json["OemPrivileges"] = nlohmann::json::array();
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+class Roles : public Node
+{
+  public:
+    Roles(CrowApp& app) :
+        Node(app, "/redfish/v1/AccountService/Roles/Administrator/")
+    {
+        Node::json["@odata.id"] =
+            "/redfish/v1/AccountService/Roles/Administrator";
+        Node::json["@odata.type"] = "#Role.v1_0_2.Role";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Role.Role";
+        Node::json["Id"] = "Administrator";
+        Node::json["Name"] = "User Role";
+        Node::json["Description"] = "Administrator User Role";
+        Node::json["IsPredefined"] = true;
+        Node::json["AssignedPrivileges"] = {"Login", "ConfigureManager",
+                                            "ConfigureUsers", "ConfigureSelf",
+                                            "ConfigureComponents"};
+        Node::json["OemPrivileges"] = nlohmann::json::array();
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
 };
 
-class RoleCollection : public Node {
- public:
-  RoleCollection(CrowApp& app)
-      : Node(app, "/redfish/v1/AccountService/Roles/") {
-    Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
-    Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#RoleCollection.RoleCollection";
-    Node::json["Name"] = "Roles Collection";
-    Node::json["Description"] = "BMC User Roles";
-    Node::json["Members@odata.count"] = 1;
-    Node::json["Members"] = {
-        {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
+class RoleCollection : public Node
+{
+  public:
+    RoleCollection(CrowApp& app) :
+        Node(app, "/redfish/v1/AccountService/Roles/")
+    {
+        Node::json["@odata.id"] = "/redfish/v1/AccountService/Roles";
+        Node::json["@odata.type"] = "#RoleCollection.RoleCollection";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#RoleCollection.RoleCollection";
+        Node::json["Name"] = "Roles Collection";
+        Node::json["Description"] = "BMC User Roles";
+        Node::json["Members@odata.count"] = 1;
+        Node::json["Members"] = {
+            {{"@odata.id", "/redfish/v1/AccountService/Roles/Administrator"}}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
+    }
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    // This is a short term solution to work around a bug.  GetSubroutes
-    // accidentally recognizes the Roles/Administrator route as a subroute
-    // (because it's hardcoded to a single entity).  Remove this line when that
-    // is resolved
-    res.jsonValue.erase("Administrator");
-    res.end();
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        // This is a short term solution to work around a bug.  GetSubroutes
+        // accidentally recognizes the Roles/Administrator route as a subroute
+        // (because it's hardcoded to a single entity).  Remove this line when
+        // that is resolved
+        res.jsonValue.erase("Administrator");
+        res.end();
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index 7f9fa68..c390cd7 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -16,13 +16,15 @@
 #pragma once
 
 #include <math.h>
-#include <dbus_singleton.hpp>
+
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/container/flat_map.hpp>
 #include <boost/range/algorithm/replace_copy_if.hpp>
+#include <dbus_singleton.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
 constexpr const char* dbusSensorPrefix = "/xyz/openbmc_project/sensors/";
 
@@ -41,32 +43,38 @@
  * SensorsAsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class SensorsAsyncResp {
- public:
-  SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
-                   const std::initializer_list<const char*> types)
-      : res(response), chassisId(chassisId), types(types) {
-    res.jsonValue["@odata.id"] =
-        "/redfish/v1/Chassis/" + chassisId + "/Thermal";
-  }
-
-  ~SensorsAsyncResp() {
-    if (res.result() == boost::beast::http::status::internal_server_error) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = nlohmann::json::object();
+class SensorsAsyncResp
+{
+  public:
+    SensorsAsyncResp(crow::Response& response, const std::string& chassisId,
+                     const std::initializer_list<const char*> types) :
+        res(response),
+        chassisId(chassisId), types(types)
+    {
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/Chassis/" + chassisId + "/Thermal";
     }
-    res.end();
-  }
 
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
+    ~SensorsAsyncResp()
+    {
+        if (res.result() == boost::beast::http::status::internal_server_error)
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = nlohmann::json::object();
+        }
+        res.end();
+    }
 
-  crow::Response& res;
-  std::string chassisId{};
-  const std::vector<const char*> types;
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
+    }
+
+    crow::Response& res;
+    std::string chassisId{};
+    const std::vector<const char*> types;
 };
 
 /**
@@ -78,70 +86,84 @@
 template <typename Callback>
 void getConnections(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
                     const boost::container::flat_set<std::string>& sensorNames,
-                    Callback&& callback) {
-  BMCWEB_LOG_DEBUG << "getConnections enter";
-  const std::string path = "/xyz/openbmc_project/sensors";
-  const std::array<std::string, 1> interfaces = {
-      "xyz.openbmc_project.Sensor.Value"};
+                    Callback&& callback)
+{
+    BMCWEB_LOG_DEBUG << "getConnections enter";
+    const std::string path = "/xyz/openbmc_project/sensors";
+    const std::array<std::string, 1> interfaces = {
+        "xyz.openbmc_project.Sensor.Value"};
 
-  // Response handler for parsing objects subtree
-  auto respHandler =
-      [ callback{std::move(callback)}, SensorsAsyncResp, sensorNames ](
-          const boost::system::error_code ec, const GetSubTreeType& subtree) {
-    BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
-    if (ec) {
-      SensorsAsyncResp->setErrorStatus();
-      BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error " << ec;
-      return;
-    }
-
-    BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
-
-    // Make unique list of connections only for requested sensor types and
-    // found in the chassis
-    boost::container::flat_set<std::string> connections;
-    // Intrinsic to avoid malloc.  Most systems will have < 8 sensor producers
-    connections.reserve(8);
-
-    BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
-    for (const std::string& tsensor : sensorNames) {
-      BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
-    }
-
-    for (const std::pair<
-             std::string,
-             std::vector<std::pair<std::string, std::vector<std::string>>>>&
-             object : subtree) {
-      for (const char* type : SensorsAsyncResp->types) {
-        if (boost::starts_with(object.first, type)) {
-          auto lastPos = object.first.rfind('/');
-          if (lastPos != std::string::npos) {
-            std::string sensorName = object.first.substr(lastPos + 1);
-
-            if (sensorNames.find(sensorName) != sensorNames.end()) {
-              // For each Connection name
-              for (const std::pair<std::string, std::vector<std::string>>&
-                       objData : object.second) {
-                BMCWEB_LOG_DEBUG << "Adding connection: " << objData.first;
-                connections.insert(objData.first);
-              }
-            }
-          }
-          break;
+    // Response handler for parsing objects subtree
+    auto respHandler = [callback{std::move(callback)}, SensorsAsyncResp,
+                        sensorNames](const boost::system::error_code ec,
+                                     const GetSubTreeType& subtree) {
+        BMCWEB_LOG_DEBUG << "getConnections resp_handler enter";
+        if (ec)
+        {
+            SensorsAsyncResp->setErrorStatus();
+            BMCWEB_LOG_ERROR << "getConnections resp_handler: Dbus error "
+                             << ec;
+            return;
         }
-      }
-    }
-    BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
-    callback(std::move(connections));
-    BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
-  };
 
-  // Make call to ObjectMapper to find all sensors objects
-  crow::connections::systemBus->async_method_call(
-      std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
-      "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
-      "GetSubTree", path, 2, interfaces);
-  BMCWEB_LOG_DEBUG << "getConnections exit";
+        BMCWEB_LOG_DEBUG << "Found " << subtree.size() << " subtrees";
+
+        // Make unique list of connections only for requested sensor types and
+        // found in the chassis
+        boost::container::flat_set<std::string> connections;
+        // Intrinsic to avoid malloc.  Most systems will have < 8 sensor
+        // producers
+        connections.reserve(8);
+
+        BMCWEB_LOG_DEBUG << "sensorNames list count: " << sensorNames.size();
+        for (const std::string& tsensor : sensorNames)
+        {
+            BMCWEB_LOG_DEBUG << "Sensor to find: " << tsensor;
+        }
+
+        for (const std::pair<
+                 std::string,
+                 std::vector<std::pair<std::string, std::vector<std::string>>>>&
+                 object : subtree)
+        {
+            for (const char* type : SensorsAsyncResp->types)
+            {
+                if (boost::starts_with(object.first, type))
+                {
+                    auto lastPos = object.first.rfind('/');
+                    if (lastPos != std::string::npos)
+                    {
+                        std::string sensorName =
+                            object.first.substr(lastPos + 1);
+
+                        if (sensorNames.find(sensorName) != sensorNames.end())
+                        {
+                            // For each Connection name
+                            for (const std::pair<std::string,
+                                                 std::vector<std::string>>&
+                                     objData : object.second)
+                            {
+                                BMCWEB_LOG_DEBUG << "Adding connection: "
+                                                 << objData.first;
+                                connections.insert(objData.first);
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+        BMCWEB_LOG_DEBUG << "Found " << connections.size() << " connections";
+        callback(std::move(connections));
+        BMCWEB_LOG_DEBUG << "getConnections resp_handler exit";
+    };
+
+    // Make call to ObjectMapper to find all sensors objects
+    crow::connections::systemBus->async_method_call(
+        std::move(respHandler), "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 2, interfaces);
+    BMCWEB_LOG_DEBUG << "getConnections exit";
 }
 
 /**
@@ -151,64 +173,74 @@
  */
 template <typename Callback>
 void getChassis(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp,
-                Callback&& callback) {
-  BMCWEB_LOG_DEBUG << "getChassis enter";
-  // Process response from EntityManager and extract chassis data
-  auto respHandler = [ callback{std::move(callback)}, SensorsAsyncResp ](
-      const boost::system::error_code ec, ManagedObjectsVectorType& resp) {
-    BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
-    if (ec) {
-      BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
-      SensorsAsyncResp->setErrorStatus();
-      return;
-    }
-    boost::container::flat_set<std::string> sensorNames;
+                Callback&& callback)
+{
+    BMCWEB_LOG_DEBUG << "getChassis enter";
+    // Process response from EntityManager and extract chassis data
+    auto respHandler = [callback{std::move(callback)},
+                        SensorsAsyncResp](const boost::system::error_code ec,
+                                          ManagedObjectsVectorType& resp) {
+        BMCWEB_LOG_DEBUG << "getChassis respHandler enter";
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR << "getChassis respHandler DBUS error: " << ec;
+            SensorsAsyncResp->setErrorStatus();
+            return;
+        }
+        boost::container::flat_set<std::string> sensorNames;
 
-    //   SensorsAsyncResp->chassisId
-    bool foundChassis = false;
-    std::vector<std::string> split;
-    // Reserve space for
-    // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
-    split.reserve(8);
+        //   SensorsAsyncResp->chassisId
+        bool foundChassis = false;
+        std::vector<std::string> split;
+        // Reserve space for
+        // /xyz/openbmc_project/inventory/<name>/<subname> + 3 subnames
+        split.reserve(8);
 
-    for (const auto& objDictEntry : resp) {
-      const std::string& objectPath =
-          static_cast<const std::string&>(objDictEntry.first);
-      boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
-      if (split.size() < 2) {
-        BMCWEB_LOG_ERROR << "Got path that isn't long enough " << objectPath;
-        split.clear();
-        continue;
-      }
-      const std::string& sensorName = split.end()[-1];
-      const std::string& chassisName = split.end()[-2];
+        for (const auto& objDictEntry : resp)
+        {
+            const std::string& objectPath =
+                static_cast<const std::string&>(objDictEntry.first);
+            boost::algorithm::split(split, objectPath, boost::is_any_of("/"));
+            if (split.size() < 2)
+            {
+                BMCWEB_LOG_ERROR << "Got path that isn't long enough "
+                                 << objectPath;
+                split.clear();
+                continue;
+            }
+            const std::string& sensorName = split.end()[-1];
+            const std::string& chassisName = split.end()[-2];
 
-      if (chassisName != SensorsAsyncResp->chassisId) {
-        split.clear();
-        continue;
-      }
-      BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
-      foundChassis = true;
-      sensorNames.emplace(sensorName);
-      split.clear();
+            if (chassisName != SensorsAsyncResp->chassisId)
+            {
+                split.clear();
+                continue;
+            }
+            BMCWEB_LOG_DEBUG << "New sensor: " << sensorName;
+            foundChassis = true;
+            sensorNames.emplace(sensorName);
+            split.clear();
+        };
+        BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
+
+        if (!foundChassis)
+        {
+            BMCWEB_LOG_INFO << "Unable to find chassis named "
+                            << SensorsAsyncResp->chassisId;
+            SensorsAsyncResp->res.result(boost::beast::http::status::not_found);
+        }
+        else
+        {
+            callback(sensorNames);
+        }
+        BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
     };
-    BMCWEB_LOG_DEBUG << "Found " << sensorNames.size() << " Sensor names";
 
-    if (!foundChassis) {
-      BMCWEB_LOG_INFO << "Unable to find chassis named "
-                      << SensorsAsyncResp->chassisId;
-      SensorsAsyncResp->res.result(boost::beast::http::status::not_found);
-    } else {
-      callback(sensorNames);
-    }
-    BMCWEB_LOG_DEBUG << "getChassis respHandler exit";
-  };
-
-  // Make call to EntityManager to find all chassis objects
-  crow::connections::systemBus->async_method_call(
-      respHandler, "xyz.openbmc_project.EntityManager", "/",
-      "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-  BMCWEB_LOG_DEBUG << "getChassis exit";
+    // Make call to EntityManager to find all chassis objects
+    crow::connections::systemBus->async_method_call(
+        respHandler, "xyz.openbmc_project.EntityManager", "/",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    BMCWEB_LOG_DEBUG << "getChassis exit";
 }
 
 /**
@@ -225,116 +257,146 @@
     const boost::container::flat_map<
         std::string, boost::container::flat_map<std::string, SensorVariant>>&
         interfacesDict,
-    nlohmann::json& sensor_json) {
-  // We need a value interface before we can do anything with it
-  auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
-  if (valueIt == interfacesDict.end()) {
-    BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
-    return;
-  }
-
-  // Assume values exist as is (10^0 == 1) if no scale exists
-  int64_t scaleMultiplier = 0;
-
-  auto scaleIt = valueIt->second.find("Scale");
-  // If a scale exists, pull value as int64, and use the scaling.
-  if (scaleIt != valueIt->second.end()) {
-    const int64_t* int64Value = mapbox::getPtr<const int64_t>(scaleIt->second);
-    if (int64Value != nullptr) {
-      scaleMultiplier = *int64Value;
+    nlohmann::json& sensor_json)
+{
+    // We need a value interface before we can do anything with it
+    auto valueIt = interfacesDict.find("xyz.openbmc_project.Sensor.Value");
+    if (valueIt == interfacesDict.end())
+    {
+        BMCWEB_LOG_ERROR << "Sensor doesn't have a value interface";
+        return;
     }
-  }
 
-  sensor_json["MemberId"] = sensorName;
-  sensor_json["Name"] = sensorName;
-  sensor_json["Status"]["State"] = "Enabled";
-  sensor_json["Status"]["Health"] = "OK";
+    // Assume values exist as is (10^0 == 1) if no scale exists
+    int64_t scaleMultiplier = 0;
 
-  // Parameter to set to override the type we get from dbus, and force it to
-  // int, regardless of what is available.  This is used for schemas like fan,
-  // that require integers, not floats.
-  bool forceToInt = false;
-
-  const char* unit = "Reading";
-  if (sensorType == "temperature") {
-    unit = "ReadingCelsius";
-    sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
-    // TODO(ed) Documentation says that path should be type fan_tach,
-    // implementation seems to implement fan
-  } else if (sensorType == "fan" || sensorType == "fan_tach") {
-    unit = "Reading";
-    sensor_json["ReadingUnits"] = "RPM";
-    sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
-    forceToInt = true;
-  } else if (sensorType == "voltage") {
-    unit = "ReadingVolts";
-    sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
-  } else {
-    BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
-    return;
-  }
-  // Map of dbus interface name, dbus property name and redfish property_name
-  std::vector<std::tuple<const char*, const char*, const char*>> properties;
-  properties.reserve(7);
-
-  properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
-                          "WarningHigh", "UpperThresholdNonCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
-                          "WarningLow", "LowerThresholdNonCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
-                          "CriticalHigh", "UpperThresholdCritical");
-  properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
-                          "CriticalLow", "LowerThresholdCritical");
-
-  if (sensorType == "temperature") {
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
-                            "MinReadingRangeTemp");
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
-                            "MaxReadingRangeTemp");
-  } else {
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
-                            "MinReadingRange");
-    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
-                            "MaxReadingRange");
-  }
-
-  for (const std::tuple<const char*, const char*, const char*>& p :
-       properties) {
-    auto interfaceProperties = interfacesDict.find(std::get<0>(p));
-    if (interfaceProperties != interfacesDict.end()) {
-      auto valueIt = interfaceProperties->second.find(std::get<1>(p));
-      if (valueIt != interfaceProperties->second.end()) {
-        const SensorVariant& valueVariant = valueIt->second;
-        nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
-
-        // Attempt to pull the int64 directly
-        const int64_t* int64Value = mapbox::getPtr<const int64_t>(valueVariant);
-
-        if (int64Value != nullptr) {
-          if (forceToInt || scaleMultiplier >= 0) {
-            valueIt = *int64Value * std::pow(10, scaleMultiplier);
-          } else {
-            valueIt = *int64Value *
-                      std::pow(10, static_cast<double>(scaleMultiplier));
-          }
+    auto scaleIt = valueIt->second.find("Scale");
+    // If a scale exists, pull value as int64, and use the scaling.
+    if (scaleIt != valueIt->second.end())
+    {
+        const int64_t* int64Value =
+            mapbox::getPtr<const int64_t>(scaleIt->second);
+        if (int64Value != nullptr)
+        {
+            scaleMultiplier = *int64Value;
         }
-        // Attempt to pull the float directly
-        const double* doubleValue = mapbox::getPtr<const double>(valueVariant);
-
-        if (doubleValue != nullptr) {
-          if (!forceToInt) {
-            valueIt = *doubleValue *
-                      std::pow(10, static_cast<double>(scaleMultiplier));
-          } else {
-            valueIt = static_cast<int64_t>(*doubleValue *
-                                           std::pow(10, scaleMultiplier));
-          }
-        }
-      }
     }
-  }
-  BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
+
+    sensor_json["MemberId"] = sensorName;
+    sensor_json["Name"] = sensorName;
+    sensor_json["Status"]["State"] = "Enabled";
+    sensor_json["Status"]["Health"] = "OK";
+
+    // Parameter to set to override the type we get from dbus, and force it to
+    // int, regardless of what is available.  This is used for schemas like fan,
+    // that require integers, not floats.
+    bool forceToInt = false;
+
+    const char* unit = "Reading";
+    if (sensorType == "temperature")
+    {
+        unit = "ReadingCelsius";
+        sensor_json["@odata.type"] = "#Thermal.v1_3_0.Temperature";
+        // TODO(ed) Documentation says that path should be type fan_tach,
+        // implementation seems to implement fan
+    }
+    else if (sensorType == "fan" || sensorType == "fan_tach")
+    {
+        unit = "Reading";
+        sensor_json["ReadingUnits"] = "RPM";
+        sensor_json["@odata.type"] = "#Thermal.v1_3_0.Fan";
+        forceToInt = true;
+    }
+    else if (sensorType == "voltage")
+    {
+        unit = "ReadingVolts";
+        sensor_json["@odata.type"] = "#Power.v1_0_0.Voltage";
+    }
+    else
+    {
+        BMCWEB_LOG_ERROR << "Redfish cannot map object type for " << sensorName;
+        return;
+    }
+    // Map of dbus interface name, dbus property name and redfish property_name
+    std::vector<std::tuple<const char*, const char*, const char*>> properties;
+    properties.reserve(7);
+
+    properties.emplace_back("xyz.openbmc_project.Sensor.Value", "Value", unit);
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                            "WarningHigh", "UpperThresholdNonCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Warning",
+                            "WarningLow", "LowerThresholdNonCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                            "CriticalHigh", "UpperThresholdCritical");
+    properties.emplace_back("xyz.openbmc_project.Sensor.Threshold.Critical",
+                            "CriticalLow", "LowerThresholdCritical");
+
+    if (sensorType == "temperature")
+    {
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                                "MinReadingRangeTemp");
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                                "MaxReadingRangeTemp");
+    }
+    else
+    {
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MinValue",
+                                "MinReadingRange");
+        properties.emplace_back("xyz.openbmc_project.Sensor.Value", "MaxValue",
+                                "MaxReadingRange");
+    }
+
+    for (const std::tuple<const char*, const char*, const char*>& p :
+         properties)
+    {
+        auto interfaceProperties = interfacesDict.find(std::get<0>(p));
+        if (interfaceProperties != interfacesDict.end())
+        {
+            auto valueIt = interfaceProperties->second.find(std::get<1>(p));
+            if (valueIt != interfaceProperties->second.end())
+            {
+                const SensorVariant& valueVariant = valueIt->second;
+                nlohmann::json& valueIt = sensor_json[std::get<2>(p)];
+
+                // Attempt to pull the int64 directly
+                const int64_t* int64Value =
+                    mapbox::getPtr<const int64_t>(valueVariant);
+
+                if (int64Value != nullptr)
+                {
+                    if (forceToInt || scaleMultiplier >= 0)
+                    {
+                        valueIt = *int64Value * std::pow(10, scaleMultiplier);
+                    }
+                    else
+                    {
+                        valueIt =
+                            *int64Value *
+                            std::pow(10, static_cast<double>(scaleMultiplier));
+                    }
+                }
+                // Attempt to pull the float directly
+                const double* doubleValue =
+                    mapbox::getPtr<const double>(valueVariant);
+
+                if (doubleValue != nullptr)
+                {
+                    if (!forceToInt)
+                    {
+                        valueIt =
+                            *doubleValue *
+                            std::pow(10, static_cast<double>(scaleMultiplier));
+                    }
+                    else
+                    {
+                        valueIt = static_cast<int64_t>(
+                            *doubleValue * std::pow(10, scaleMultiplier));
+                    }
+                }
+            }
+        }
+    }
+    BMCWEB_LOG_DEBUG << "Added sensor " << sensorName;
 }
 
 /**
@@ -342,106 +404,140 @@
  *        chassis.
  * @param SensorsAsyncResp   Pointer to object holding response data
  */
-void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp) {
-  BMCWEB_LOG_DEBUG << "getChassisData enter";
-  auto getChassisCb = [&, SensorsAsyncResp](
-                          boost::container::flat_set<std::string>&
-                              sensorNames) {
-    BMCWEB_LOG_DEBUG << "getChassisCb enter";
-    auto getConnectionCb =
-        [&, SensorsAsyncResp, sensorNames](
-            const boost::container::flat_set<std::string>& connections) {
-          BMCWEB_LOG_DEBUG << "getConnectionCb enter";
-          // Get managed objects from all services exposing sensors
-          for (const std::string& connection : connections) {
-            // Response handler to process managed objects
-            auto getManagedObjectsCb = [&, SensorsAsyncResp, sensorNames](
-                                           const boost::system::error_code ec,
-                                           ManagedObjectsVectorType& resp) {
-              BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
-              if (ec) {
-                BMCWEB_LOG_ERROR << "getManagedObjectsCb DBUS error: " << ec;
-                SensorsAsyncResp->setErrorStatus();
-                return;
-              }
-              // Go through all objects and update response with
-              // sensor data
-              for (const auto& objDictEntry : resp) {
-                const std::string& objPath =
-                    static_cast<const std::string&>(objDictEntry.first);
-                BMCWEB_LOG_DEBUG << "getManagedObjectsCb parsing object "
-                                 << objPath;
+void getChassisData(std::shared_ptr<SensorsAsyncResp> SensorsAsyncResp)
+{
+    BMCWEB_LOG_DEBUG << "getChassisData enter";
+    auto getChassisCb = [&, SensorsAsyncResp](
+                            boost::container::flat_set<std::string>&
+                                sensorNames) {
+        BMCWEB_LOG_DEBUG << "getChassisCb enter";
+        auto getConnectionCb =
+            [&, SensorsAsyncResp, sensorNames](
+                const boost::container::flat_set<std::string>& connections) {
+                BMCWEB_LOG_DEBUG << "getConnectionCb enter";
+                // Get managed objects from all services exposing sensors
+                for (const std::string& connection : connections)
+                {
+                    // Response handler to process managed objects
+                    auto getManagedObjectsCb =
+                        [&, SensorsAsyncResp,
+                         sensorNames](const boost::system::error_code ec,
+                                      ManagedObjectsVectorType& resp) {
+                            BMCWEB_LOG_DEBUG << "getManagedObjectsCb enter";
+                            if (ec)
+                            {
+                                BMCWEB_LOG_ERROR
+                                    << "getManagedObjectsCb DBUS error: " << ec;
+                                SensorsAsyncResp->setErrorStatus();
+                                return;
+                            }
+                            // Go through all objects and update response with
+                            // sensor data
+                            for (const auto& objDictEntry : resp)
+                            {
+                                const std::string& objPath =
+                                    static_cast<const std::string&>(
+                                        objDictEntry.first);
+                                BMCWEB_LOG_DEBUG
+                                    << "getManagedObjectsCb parsing object "
+                                    << objPath;
 
-                std::vector<std::string> split;
-                // Reserve space for
-                // /xyz/openbmc_project/sensors/<name>/<subname>
-                split.reserve(6);
-                boost::algorithm::split(split, objPath, boost::is_any_of("/"));
-                if (split.size() < 6) {
-                  BMCWEB_LOG_ERROR << "Got path that isn't long enough "
-                                   << objPath;
-                  continue;
-                }
-                // These indexes aren't intuitive, as boost::split puts an empty
-                // string at the beggining
-                const std::string& sensorType = split[4];
-                const std::string& sensorName = split[5];
-                BMCWEB_LOG_DEBUG << "sensorName " << sensorName
-                                 << " sensorType " << sensorType;
-                if (sensorNames.find(sensorName) == sensorNames.end()) {
-                  BMCWEB_LOG_ERROR << sensorName << " not in sensor list ";
-                  continue;
-                }
+                                std::vector<std::string> split;
+                                // Reserve space for
+                                // /xyz/openbmc_project/sensors/<name>/<subname>
+                                split.reserve(6);
+                                boost::algorithm::split(split, objPath,
+                                                        boost::is_any_of("/"));
+                                if (split.size() < 6)
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "Got path that isn't long enough "
+                                        << objPath;
+                                    continue;
+                                }
+                                // These indexes aren't intuitive, as
+                                // boost::split puts an empty string at the
+                                // beggining
+                                const std::string& sensorType = split[4];
+                                const std::string& sensorName = split[5];
+                                BMCWEB_LOG_DEBUG << "sensorName " << sensorName
+                                                 << " sensorType "
+                                                 << sensorType;
+                                if (sensorNames.find(sensorName) ==
+                                    sensorNames.end())
+                                {
+                                    BMCWEB_LOG_ERROR << sensorName
+                                                     << " not in sensor list ";
+                                    continue;
+                                }
 
-                const char* fieldName = nullptr;
-                if (sensorType == "temperature") {
-                  fieldName = "Temperatures";
-                } else if (sensorType == "fan" || sensorType == "fan_tach") {
-                  fieldName = "Fans";
-                } else if (sensorType == "voltage") {
-                  fieldName = "Voltages";
-                } else if (sensorType == "current") {
-                  fieldName = "PowerSupply";
-                } else if (sensorType == "power") {
-                  fieldName = "PowerSupply";
-                } else {
-                  BMCWEB_LOG_ERROR << "Unsure how to handle sensorType "
-                                   << sensorType;
-                  continue;
-                }
+                                const char* fieldName = nullptr;
+                                if (sensorType == "temperature")
+                                {
+                                    fieldName = "Temperatures";
+                                }
+                                else if (sensorType == "fan" ||
+                                         sensorType == "fan_tach")
+                                {
+                                    fieldName = "Fans";
+                                }
+                                else if (sensorType == "voltage")
+                                {
+                                    fieldName = "Voltages";
+                                }
+                                else if (sensorType == "current")
+                                {
+                                    fieldName = "PowerSupply";
+                                }
+                                else if (sensorType == "power")
+                                {
+                                    fieldName = "PowerSupply";
+                                }
+                                else
+                                {
+                                    BMCWEB_LOG_ERROR
+                                        << "Unsure how to handle sensorType "
+                                        << sensorType;
+                                    continue;
+                                }
 
-                nlohmann::json& tempArray =
-                    SensorsAsyncResp->res.jsonValue[fieldName];
+                                nlohmann::json& tempArray =
+                                    SensorsAsyncResp->res.jsonValue[fieldName];
 
-                // Create the array if it doesn't yet exist
-                if (tempArray.is_array() == false) {
-                  tempArray = nlohmann::json::array();
-                }
+                                // Create the array if it doesn't yet exist
+                                if (tempArray.is_array() == false)
+                                {
+                                    tempArray = nlohmann::json::array();
+                                }
 
-                tempArray.push_back(
-                    {{"@odata.id", "/redfish/v1/Chassis/" +
-                                       SensorsAsyncResp->chassisId +
-                                       "/Thermal#/" + sensorName}});
-                nlohmann::json& sensorJson = tempArray.back();
-                objectInterfacesToJson(sensorName, sensorType,
-                                       objDictEntry.second, sensorJson);
-              }
-              BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
+                                tempArray.push_back(
+                                    {{"@odata.id",
+                                      "/redfish/v1/Chassis/" +
+                                          SensorsAsyncResp->chassisId +
+                                          "/Thermal#/" + sensorName}});
+                                nlohmann::json& sensorJson = tempArray.back();
+                                objectInterfacesToJson(sensorName, sensorType,
+                                                       objDictEntry.second,
+                                                       sensorJson);
+                            }
+                            BMCWEB_LOG_DEBUG << "getManagedObjectsCb exit";
+                        };
+                    crow::connections::systemBus->async_method_call(
+                        getManagedObjectsCb, connection, "/",
+                        "org.freedesktop.DBus.ObjectManager",
+                        "GetManagedObjects");
+                };
+                BMCWEB_LOG_DEBUG << "getConnectionCb exit";
             };
-            crow::connections::systemBus->async_method_call(
-                getManagedObjectsCb, connection, "/",
-                "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
-          };
-          BMCWEB_LOG_DEBUG << "getConnectionCb exit";
-        };
-    // get connections and then pass it to get sensors
-    getConnections(SensorsAsyncResp, sensorNames, std::move(getConnectionCb));
-    BMCWEB_LOG_DEBUG << "getChassisCb exit";
-  };
+        // get connections and then pass it to get sensors
+        getConnections(SensorsAsyncResp, sensorNames,
+                       std::move(getConnectionCb));
+        BMCWEB_LOG_DEBUG << "getChassisCb exit";
+    };
 
-  // get chassis information related to sensors
-  getChassis(SensorsAsyncResp, std::move(getChassisCb));
-  BMCWEB_LOG_DEBUG << "getChassisData exit";
+    // get chassis information related to sensors
+    getChassis(SensorsAsyncResp, std::move(getChassisCb));
+    BMCWEB_LOG_DEBUG << "getChassisData exit";
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 6fa9632..d2c5163 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -15,62 +15,69 @@
 */
 #pragma once
 
-#include <systemd/sd-id128.h>
 #include "node.hpp"
 
-namespace redfish {
+#include <systemd/sd-id128.h>
 
-class ServiceRoot : public Node {
- public:
-  ServiceRoot(CrowApp& app) : Node(app, "/redfish/v1/") {
-    Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
-    Node::json["@odata.id"] = "/redfish/v1/";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
-    Node::json["Id"] = "RootService";
-    Node::json["Name"] = "Root Service";
-    Node::json["RedfishVersion"] = "1.1.0";
-    Node::json["Links"]["Sessions"] = {
-        {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
+namespace redfish
+{
 
-    Node::json["UUID"] = getUuid();
+class ServiceRoot : public Node
+{
+  public:
+    ServiceRoot(CrowApp& app) : Node(app, "/redfish/v1/")
+    {
+        Node::json["@odata.type"] = "#ServiceRoot.v1_1_1.ServiceRoot";
+        Node::json["@odata.id"] = "/redfish/v1/";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
+        Node::json["Id"] = "RootService";
+        Node::json["Name"] = "Root Service";
+        Node::json["RedfishVersion"] = "1.1.0";
+        Node::json["Links"]["Sessions"] = {
+            {"@odata.id", "/redfish/v1/SessionService/Sessions"}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {}},
-        {boost::beast::http::verb::head, {}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        Node::json["UUID"] = getUuid();
 
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
-
-  const std::string getUuid() {
-  // If we are using a version of systemd that can get the app specific uuid,
-  // use that
-#ifdef sd_id128_get_machine_app_specific
-    std::array<char, SD_ID128_STRING_MAX> string;
-    sd_id128_t id = SD_ID128_NULL;
-
-    // This ID needs to match the one in ipmid
-    int r = sd_id128_get_machine_app_specific(
-        SD_ID128_MAKE(e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64, 12,
-                      45, 78),
-        &id);
-    if (r < 0) {
-      return "00000000-0000-0000-0000-000000000000";
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {}},
+            {boost::beast::http::verb::head, {}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
-    return string.data();
+
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        res.jsonValue = Node::json;
+        res.end();
+    }
+
+    const std::string getUuid()
+    {
+        // If we are using a version of systemd that can get the app specific
+        // uuid, use that
+#ifdef sd_id128_get_machine_app_specific
+        std::array<char, SD_ID128_STRING_MAX> string;
+        sd_id128_t id = SD_ID128_NULL;
+
+        // This ID needs to match the one in ipmid
+        int r = sd_id128_get_machine_app_specific(
+            SD_ID128_MAKE(e0, e1, 73, 76, 64, 61, 47, da, a5, 0c, d0, cc, 64,
+                          12, 45, 78),
+            &id);
+        if (r < 0)
+        {
+            return "00000000-0000-0000-0000-000000000000";
+        }
+        return string.data();
 #else
-    return "00000000-0000-0000-0000-000000000000";
+        return "00000000-0000-0000-0000-000000000000";
 #endif
-  }
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index b7f91b9..cd49883 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -15,36 +15,44 @@
 */
 #pragma once
 
+#include "boost/container/flat_map.hpp"
+#include "node.hpp"
+
 #include <error_messages.hpp>
 #include <utils/json_utils.hpp>
-#include "node.hpp"
-#include "boost/container/flat_map.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
 /**
  * SystemAsyncResp
  * Gathers data needed for response processing after async calls are done
  */
-class SystemAsyncResp {
- public:
-  SystemAsyncResp(crow::Response &response) : res(response) {}
-
-  ~SystemAsyncResp() {
-    if (res.result() != (boost::beast::http::status::ok)) {
-      // Reset the json object to clear out any data that made it in before the
-      // error happened
-      // todo(ed) handle error condition with proper code
-      res.jsonValue = messages::internalError();
+class SystemAsyncResp
+{
+  public:
+    SystemAsyncResp(crow::Response &response) : res(response)
+    {
     }
-    res.end();
-  }
 
-  void setErrorStatus() {
-    res.result(boost::beast::http::status::internal_server_error);
-  }
+    ~SystemAsyncResp()
+    {
+        if (res.result() != (boost::beast::http::status::ok))
+        {
+            // Reset the json object to clear out any data that made it in
+            // before the error happened todo(ed) handle error condition with
+            // proper code
+            res.jsonValue = messages::internalError();
+        }
+        res.end();
+    }
 
-  crow::Response &res;
+    void setErrorStatus()
+    {
+        res.result(boost::beast::http::status::internal_server_error);
+    }
+
+    crow::Response &res;
 };
 
 /**
@@ -59,628 +67,853 @@
  * This perhaps shall be different file, which has to be chosen on compile time
  * depending on OEM needs
  */
-class OnDemandSystemsProvider {
- public:
-  template <typename CallbackFunc>
-  void getBaseboardList(CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get list of available boards.";
-    crow::connections::systemBus->async_method_call(
-        [callback{std::move(callback)}](const boost::system::error_code ec,
-                                        const std::vector<std::string> &resp) {
-          // Callback requires vector<string> to retrieve all available board
-          // list.
-          std::vector<std::string> boardList;
-          if (ec) {
-            // Something wrong on DBus, the error_code is not important at this
-            // moment, just return success=false, and empty output. Since size
-            // of vector may vary depending on information from Entity Manager,
-            // and empty output could not be treated same way as error.
-            callback(false, boardList);
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::string &objpath : resp) {
-            std::size_t lastPos = objpath.rfind("/");
-            if (lastPos != std::string::npos) {
-              boardList.emplace_back(objpath.substr(lastPos + 1));
-            }
-          }
-          // Finally make a callback with useful data
-          callback(true, boardList);
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-        "/xyz/openbmc_project/inventory", int32_t(0),
-        std::array<const char *, 1>{
-            "xyz.openbmc_project.Inventory.Item.Board"});
-  };
-
-  /**
-   * @brief Retrieves computer system properties over dbus
-   *
-   * @param[in] aResp Shared pointer for completing asynchronous calls
-   * @param[in] name  Computer system name from request
-   *
-   * @return None.
-   */
-  void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp,
-                         const std::string &name) {
-    const std::array<const char *, 5> interfaces = {
-        "xyz.openbmc_project.Inventory.Decorator.Asset",
-        "xyz.openbmc_project.Inventory.Item.Cpu",
-        "xyz.openbmc_project.Inventory.Item.Dimm",
-        "xyz.openbmc_project.Inventory.Item.System",
-        "xyz.openbmc_project.Common.UUID",
+class OnDemandSystemsProvider
+{
+  public:
+    template <typename CallbackFunc>
+    void getBaseboardList(CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get list of available boards.";
+        crow::connections::systemBus->async_method_call(
+            [callback{std::move(callback)}](
+                const boost::system::error_code ec,
+                const std::vector<std::string> &resp) {
+                // Callback requires vector<string> to retrieve all available
+                // board list.
+                std::vector<std::string> boardList;
+                if (ec)
+                {
+                    // Something wrong on DBus, the error_code is not important
+                    // at this moment, just return success=false, and empty
+                    // output. Since size of vector may vary depending on
+                    // information from Entity Manager, and empty output could
+                    // not be treated same way as error.
+                    callback(false, boardList);
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::string &objpath : resp)
+                {
+                    std::size_t lastPos = objpath.rfind("/");
+                    if (lastPos != std::string::npos)
+                    {
+                        boardList.emplace_back(objpath.substr(lastPos + 1));
+                    }
+                }
+                // Finally make a callback with useful data
+                callback(true, boardList);
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+            "/xyz/openbmc_project/inventory", int32_t(0),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Inventory.Item.Board"});
     };
-    BMCWEB_LOG_DEBUG << "Get available system components.";
-    crow::connections::systemBus->async_method_call(
-        [ name, aResp{std::move(aResp)} ](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error";
-            aResp->setErrorStatus();
-            return;
-          }
-          bool foundName = false;
-          // Iterate over all retrieved ObjectPaths.
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &object : subtree) {
-            const std::string &path = object.first;
-            BMCWEB_LOG_DEBUG << "Got path: " << path;
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connectionNames = object.second;
-            if (connectionNames.size() < 1) {
-              continue;
-            }
-            // Check if computer system exist
-            if (boost::ends_with(path, name)) {
-              foundName = true;
-              BMCWEB_LOG_DEBUG << "Found name: " << name;
-              const std::string connectionName = connectionNames[0].first;
-              crow::connections::systemBus->async_method_call(
-                  [ aResp, name(std::string(name)) ](
-                      const boost::system::error_code ec,
-                      const std::vector<std::pair<std::string, VariantType>>
-                          &propertiesList) {
-                    if (ec) {
-                      BMCWEB_LOG_ERROR << "DBUS response error: " << ec;
-                      aResp->setErrorStatus();
-                      return;
+
+    /**
+     * @brief Retrieves computer system properties over dbus
+     *
+     * @param[in] aResp Shared pointer for completing asynchronous calls
+     * @param[in] name  Computer system name from request
+     *
+     * @return None.
+     */
+    void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp,
+                           const std::string &name)
+    {
+        const std::array<const char *, 5> interfaces = {
+            "xyz.openbmc_project.Inventory.Decorator.Asset",
+            "xyz.openbmc_project.Inventory.Item.Cpu",
+            "xyz.openbmc_project.Inventory.Item.Dimm",
+            "xyz.openbmc_project.Inventory.Item.System",
+            "xyz.openbmc_project.Common.UUID",
+        };
+        BMCWEB_LOG_DEBUG << "Get available system components.";
+        crow::connections::systemBus->async_method_call(
+            [name, aResp{std::move(aResp)}](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error";
+                    aResp->setErrorStatus();
+                    return;
+                }
+                bool foundName = false;
+                // Iterate over all retrieved ObjectPaths.
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &object : subtree)
+                {
+                    const std::string &path = object.first;
+                    BMCWEB_LOG_DEBUG << "Got path: " << path;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connectionNames = object.second;
+                    if (connectionNames.size() < 1)
+                    {
+                        continue;
                     }
-                    BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
-                                     << "properties for system";
-                    for (const std::pair<std::string, VariantType> &property :
-                         propertiesList) {
-                      const std::string *value =
-                          mapbox::getPtr<const std::string>(property.second);
-                      if (value != nullptr) {
-                        aResp->res.jsonValue[property.first] = *value;
-                      }
-                    }
-                    aResp->res.jsonValue["Name"] = name;
-                    aResp->res.jsonValue["Id"] =
-                        aResp->res.jsonValue["SerialNumber"];
-                  },
-                  connectionName, path, "org.freedesktop.DBus.Properties",
-                  "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-            } else {
-              // This is not system, so check if it's cpu, dimm, UUID or BiosVer
-              for (auto const &s : connectionNames) {
-                for (auto const &i : s.second) {
-                  if (boost::ends_with(i, "Dimm")) {
-                    BMCWEB_LOG_DEBUG << "Found Dimm, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [&, aResp](const boost::system::error_code ec,
-                                   const std::vector<std::pair<
-                                       std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_ERROR << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "Dimm properties.";
-                          for (const auto &p : properties) {
-                            if (p.first == "MemorySize") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if ((value != nullptr) && (*value != "NULL")) {
-                                // Remove units char
-                                int32_t unitCoeff;
-                                if (boost::ends_with(*value, "MB")) {
-                                  unitCoeff = 1000;
-                                } else if (boost::ends_with(*value, "KB")) {
-                                  unitCoeff = 1000000;
-                                } else {
-                                  BMCWEB_LOG_ERROR
-                                      << "Unsupported memory units";
-                                  aResp->setErrorStatus();
-                                  return;
+                    // Check if computer system exist
+                    if (boost::ends_with(path, name))
+                    {
+                        foundName = true;
+                        BMCWEB_LOG_DEBUG << "Found name: " << name;
+                        const std::string connectionName =
+                            connectionNames[0].first;
+                        crow::connections::systemBus->async_method_call(
+                            [aResp, name(std::string(name))](
+                                const boost::system::error_code ec,
+                                const std::vector<
+                                    std::pair<std::string, VariantType>>
+                                    &propertiesList) {
+                                if (ec)
+                                {
+                                    BMCWEB_LOG_ERROR << "DBUS response error: "
+                                                     << ec;
+                                    aResp->setErrorStatus();
+                                    return;
                                 }
-
-                                auto memSize = boost::lexical_cast<int>(
-                                    value->substr(0, value->length() - 2));
-                                aResp->res.jsonValue["TotalSystemMemoryGiB"] +=
-                                    memSize * unitCoeff;
-                                aResp->res.jsonValue["MemorySummary"]["Status"]
-                                                    ["State"] = "Enabled";
-                              }
-                            }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Inventory.Item.Dimm");
-                  } else if (boost::ends_with(i, "Cpu")) {
-                    BMCWEB_LOG_DEBUG << "Found Cpu, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [&, aResp](const boost::system::error_code ec,
-                                   const std::vector<std::pair<
-                                       std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_ERROR << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "Cpu properties.";
-                          for (const auto &p : properties) {
-                            if (p.first == "ProcessorFamily") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if (value != nullptr) {
-                                aResp->res
-                                    .jsonValue["ProcessorSummary"]["Count"] =
-                                    aResp->res
-                                        .jsonValue["ProcessorSummary"]["Count"]
-                                        .get<int>() +
-                                    1;
-                                aResp->res.jsonValue["ProcessorSummary"]
-                                                    ["Status"]["State"] =
-                                    "Enabled";
-                                aResp->res
-                                    .jsonValue["ProcessorSummary"]["Model"] =
-                                    *value;
-                              }
-                            }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Inventory.Item.Cpu");
-                  } else if (boost::ends_with(i, "UUID")) {
-                    BMCWEB_LOG_DEBUG << "Found UUID, now get it properties.";
-                    crow::connections::systemBus->async_method_call(
-                        [aResp](const boost::system::error_code ec,
-                                const std::vector<std::pair<
-                                    std::string, VariantType>> &properties) {
-                          if (ec) {
-                            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-                            aResp->setErrorStatus();
-                            return;
-                          }
-                          BMCWEB_LOG_DEBUG << "Got " << properties.size()
-                                           << "UUID properties.";
-                          for (const std::pair<std::string, VariantType> &p :
-                               properties) {
-                            if (p.first == "BIOSVer") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              if (value != nullptr) {
-                                aResp->res.jsonValue["BiosVersion"] = *value;
-                              }
-                            }
-                            if (p.first == "UUID") {
-                              const std::string *value =
-                                  mapbox::getPtr<const std::string>(p.second);
-                              BMCWEB_LOG_DEBUG << "UUID = " << *value
-                                               << " length " << value->length();
-                              if (value != nullptr) {
-                                // Workaround for to short return str in smbios
-                                // demo app, 32 bytes are described by spec
-                                if (value->length() > 0 &&
-                                    value->length() < 32) {
-                                  std::string correctedValue = *value;
-                                  correctedValue.append(32 - value->length(),
-                                                        '0');
-                                  value = &correctedValue;
-                                } else if (value->length() == 32) {
-                                  aResp->res.jsonValue["UUID"] =
-                                      value->substr(0, 8) + "-" +
-                                      value->substr(8, 4) + "-" +
-                                      value->substr(12, 4) + "-" +
-                                      value->substr(16, 4) + "-" +
-                                      value->substr(20, 12);
+                                BMCWEB_LOG_DEBUG << "Got "
+                                                 << propertiesList.size()
+                                                 << "properties for system";
+                                for (const std::pair<std::string, VariantType>
+                                         &property : propertiesList)
+                                {
+                                    const std::string *value =
+                                        mapbox::getPtr<const std::string>(
+                                            property.second);
+                                    if (value != nullptr)
+                                    {
+                                        aResp->res.jsonValue[property.first] =
+                                            *value;
+                                    }
                                 }
-                              }
+                                aResp->res.jsonValue["Name"] = name;
+                                aResp->res.jsonValue["Id"] =
+                                    aResp->res.jsonValue["SerialNumber"];
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    }
+                    else
+                    {
+                        // This is not system, so check if it's cpu, dimm, UUID
+                        // or BiosVer
+                        for (auto const &s : connectionNames)
+                        {
+                            for (auto const &i : s.second)
+                            {
+                                if (boost::ends_with(i, "Dimm"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found Dimm, now get it properties.";
+                                    crow::connections::systemBus->async_method_call(
+                                        [&, aResp](
+                                            const boost::system::error_code ec,
+                                            const std::vector<std::pair<
+                                                std::string, VariantType>>
+                                                &properties) {
+                                            if (ec)
+                                            {
+                                                BMCWEB_LOG_ERROR
+                                                    << "DBUS response error "
+                                                    << ec;
+                                                aResp->setErrorStatus();
+                                                return;
+                                            }
+                                            BMCWEB_LOG_DEBUG
+                                                << "Got " << properties.size()
+                                                << "Dimm properties.";
+                                            for (const auto &p : properties)
+                                            {
+                                                if (p.first == "MemorySize")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    if ((value != nullptr) &&
+                                                        (*value != "NULL"))
+                                                    {
+                                                        // Remove units char
+                                                        int32_t unitCoeff;
+                                                        if (boost::ends_with(
+                                                                *value, "MB"))
+                                                        {
+                                                            unitCoeff = 1000;
+                                                        }
+                                                        else if (boost::
+                                                                     ends_with(
+                                                                         *value,
+                                                                         "KB"))
+                                                        {
+                                                            unitCoeff = 1000000;
+                                                        }
+                                                        else
+                                                        {
+                                                            BMCWEB_LOG_ERROR
+                                                                << "Unsupported"
+                                                                   " memory "
+                                                                   "units";
+                                                            aResp
+                                                                ->setErrorStatus();
+                                                            return;
+                                                        }
+
+                                                        auto memSize =
+                                                            boost::lexical_cast<
+                                                                int>(value->substr(
+                                                                0,
+                                                                value->length() -
+                                                                    2));
+                                                        aResp->res.jsonValue
+                                                            ["TotalSystemMemory"
+                                                             "GiB"] +=
+                                                            memSize * unitCoeff;
+                                                        aResp->res.jsonValue
+                                                            ["MemorySummary"]
+                                                            ["Status"]
+                                                            ["State"] =
+                                                            "Enabled";
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        s.first, path,
+                                        "org.freedesktop.DBus.Properties",
+                                        "GetAll",
+                                        "xyz.openbmc_project.Inventory.Item."
+                                        "Dimm");
+                                }
+                                else if (boost::ends_with(i, "Cpu"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found Cpu, now get it properties.";
+                                    crow::connections::systemBus
+                                        ->async_method_call(
+                                            [&, aResp](
+                                                const boost::system::error_code
+                                                    ec,
+                                                const std::vector<std::pair<
+                                                    std::string, VariantType>>
+                                                    &properties) {
+                                                if (ec)
+                                                {
+                                                    BMCWEB_LOG_ERROR
+                                                        << "DBUS response "
+                                                           "error "
+                                                        << ec;
+                                                    aResp->setErrorStatus();
+                                                    return;
+                                                }
+                                                BMCWEB_LOG_DEBUG
+                                                    << "Got "
+                                                    << properties.size()
+                                                    << "Cpu properties.";
+                                                for (const auto &p : properties)
+                                                {
+                                                    if (p.first ==
+                                                        "ProcessorFamily")
+                                                    {
+                                                        const std::string
+                                                            *value =
+                                                                mapbox::getPtr<
+                                                                    const std::
+                                                                        string>(
+                                                                    p.second);
+                                                        if (value != nullptr)
+                                                        {
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Count"] =
+                                                                aResp->res
+                                                                    .jsonValue
+                                                                        ["Proce"
+                                                                         "ssorS"
+                                                                         "ummar"
+                                                                         "y"]
+                                                                        ["Coun"
+                                                                         "t"]
+                                                                    .get<
+                                                                        int>() +
+                                                                1;
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Status"]
+                                                                ["State"] =
+                                                                "Enabled";
+                                                            aResp->res.jsonValue
+                                                                ["ProcessorSumm"
+                                                                 "ary"]
+                                                                ["Model"] =
+                                                                *value;
+                                                        }
+                                                    }
+                                                }
+                                            },
+                                            s.first, path,
+                                            "org.freedesktop.DBus.Properties",
+                                            "GetAll",
+                                            "xyz.openbmc_project.Inventory."
+                                            "Item.Cpu");
+                                }
+                                else if (boost::ends_with(i, "UUID"))
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Found UUID, now get it properties.";
+                                    crow::connections::systemBus->async_method_call(
+                                        [aResp](
+                                            const boost::system::error_code ec,
+                                            const std::vector<std::pair<
+                                                std::string, VariantType>>
+                                                &properties) {
+                                            if (ec)
+                                            {
+                                                BMCWEB_LOG_DEBUG
+                                                    << "DBUS response error "
+                                                    << ec;
+                                                aResp->setErrorStatus();
+                                                return;
+                                            }
+                                            BMCWEB_LOG_DEBUG
+                                                << "Got " << properties.size()
+                                                << "UUID properties.";
+                                            for (const std::pair<std::string,
+                                                                 VariantType>
+                                                     &p : properties)
+                                            {
+                                                if (p.first == "BIOSVer")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    if (value != nullptr)
+                                                    {
+                                                        aResp->res.jsonValue
+                                                            ["BiosVersion"] =
+                                                            *value;
+                                                    }
+                                                }
+                                                if (p.first == "UUID")
+                                                {
+                                                    const std::string *value =
+                                                        mapbox::getPtr<
+                                                            const std::string>(
+                                                            p.second);
+                                                    BMCWEB_LOG_DEBUG
+                                                        << "UUID = " << *value
+                                                        << " length "
+                                                        << value->length();
+                                                    if (value != nullptr)
+                                                    {
+                                                        // Workaround for to
+                                                        // short return str in
+                                                        // smbios demo app, 32
+                                                        // bytes are described
+                                                        // by spec
+                                                        if (value->length() >
+                                                                0 &&
+                                                            value->length() <
+                                                                32)
+                                                        {
+                                                            std::string
+                                                                correctedValue =
+                                                                    *value;
+                                                            correctedValue.append(
+                                                                32 -
+                                                                    value
+                                                                        ->length(),
+                                                                '0');
+                                                            value =
+                                                                &correctedValue;
+                                                        }
+                                                        else if (
+                                                            value->length() ==
+                                                            32)
+                                                        {
+                                                            aResp->res.jsonValue
+                                                                ["UUID"] =
+                                                                value->substr(
+                                                                    0, 8) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    8, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    12, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    16, 4) +
+                                                                "-" +
+                                                                value->substr(
+                                                                    20, 12);
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        s.first, path,
+                                        "org.freedesktop.DBus.Properties",
+                                        "GetAll",
+                                        "xyz.openbmc_project.Common.UUID");
+                                }
                             }
-                          }
-                        },
-                        s.first, path, "org.freedesktop.DBus.Properties",
-                        "GetAll", "xyz.openbmc_project.Common.UUID");
-                  }
-                }
-              }
-            }
-          }
-          if (foundName == false) {
-            aResp->setErrorStatus();
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
-  }
-
-  /**
-   * @brief Retrieves identify led group properties over dbus
-   *
-   * @param[in] aResp     Shared pointer for completing asynchronous calls.
-   * @param[in] callback  Callback for process retrieved data.
-   *
-   * @return None.
-   */
-  template <typename CallbackFunc>
-  void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp,
-                           CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get led groups";
-    crow::connections::systemBus->async_method_call(
-        [
-          aResp{std::move(aResp)}, &callback
-        ](const boost::system::error_code &ec, const ManagedObjectsType &resp) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
-          for (const auto &objPath : resp) {
-            const std::string &path = objPath.first;
-            if (path.rfind("enclosure_identify") != std::string::npos) {
-              for (const auto &interface : objPath.second) {
-                if (interface.first == "xyz.openbmc_project.Led.Group") {
-                  for (const auto &property : interface.second) {
-                    if (property.first == "Asserted") {
-                      const bool *asserted =
-                          mapbox::getPtr<const bool>(property.second);
-                      if (nullptr != asserted) {
-                        callback(*asserted, aResp);
-                      } else {
-                        callback(false, aResp);
-                      }
+                        }
                     }
-                  }
                 }
-              }
-            }
-          }
-        },
-        "xyz.openbmc_project.LED.GroupManager",
-        "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
-        "GetManagedObjects");
-  }
+                if (foundName == false)
+                {
+                    aResp->setErrorStatus();
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
+    }
 
-  template <typename CallbackFunc>
-  void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp,
-                      CallbackFunc &&callback) {
-    BMCWEB_LOG_DEBUG << "Get identify led properties";
-    crow::connections::systemBus->async_method_call(
-        [ aResp{std::move(aResp)}, &callback ](
-            const boost::system::error_code ec,
-            const PropertiesType &properties) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << properties.size() << "led properties.";
-          std::string output;
-          for (const auto &property : properties) {
-            if (property.first == "State") {
-              const std::string *s =
-                  mapbox::getPtr<std::string>(property.second);
-              if (nullptr != s) {
-                BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
-                const auto pos = s->rfind('.');
-                if (pos != std::string::npos) {
-                  auto led = s->substr(pos + 1);
-                  for (const std::pair<const char *, const char *> &p :
-                       std::array<std::pair<const char *, const char *>, 3>{
-                           {{"On", "Lit"},
-                            {"Blink", "Blinking"},
-                            {"Off", "Off"}}}) {
-                    if (led == p.first) {
-                      output = p.second;
+    /**
+     * @brief Retrieves identify led group properties over dbus
+     *
+     * @param[in] aResp     Shared pointer for completing asynchronous calls.
+     * @param[in] callback  Callback for process retrieved data.
+     *
+     * @return None.
+     */
+    template <typename CallbackFunc>
+    void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp,
+                             CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get led groups";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)},
+             &callback](const boost::system::error_code &ec,
+                        const ManagedObjectsType &resp) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << resp.size()
+                                 << "led group objects.";
+                for (const auto &objPath : resp)
+                {
+                    const std::string &path = objPath.first;
+                    if (path.rfind("enclosure_identify") != std::string::npos)
+                    {
+                        for (const auto &interface : objPath.second)
+                        {
+                            if (interface.first ==
+                                "xyz.openbmc_project.Led.Group")
+                            {
+                                for (const auto &property : interface.second)
+                                {
+                                    if (property.first == "Asserted")
+                                    {
+                                        const bool *asserted =
+                                            mapbox::getPtr<const bool>(
+                                                property.second);
+                                        if (nullptr != asserted)
+                                        {
+                                            callback(*asserted, aResp);
+                                        }
+                                        else
+                                        {
+                                            callback(false, aResp);
+                                        }
+                                    }
+                                }
+                            }
+                        }
                     }
-                  }
                 }
-              }
-            }
-          }
-          callback(output, aResp);
-        },
-        "xyz.openbmc_project.LED.Controller.identify",
-        "/xyz/openbmc_project/led/physical/identify",
-        "org.freedesktop.DBus.Properties", "GetAll",
-        "xyz.openbmc_project.Led.Physical");
-  }
+            },
+            "xyz.openbmc_project.LED.GroupManager",
+            "/xyz/openbmc_project/led/groups",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    }
 
-  /**
-   * @brief Retrieves host state properties over dbus
-   *
-   * @param[in] aResp     Shared pointer for completing asynchronous calls.
-   *
-   * @return None.
-   */
-  void getHostState(std::shared_ptr<SystemAsyncResp> aResp) {
-    BMCWEB_LOG_DEBUG << "Get host information.";
-    crow::connections::systemBus->async_method_call(
-        [aResp{std::move(aResp)}](const boost::system::error_code ec,
-                                  const PropertiesType &properties) {
-          if (ec) {
-            BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-            aResp->setErrorStatus();
-            return;
-          }
-          BMCWEB_LOG_DEBUG << "Got " << properties.size() << "host properties.";
-          for (const auto &property : properties) {
-            if (property.first == "CurrentHostState") {
-              const std::string *s =
-                  mapbox::getPtr<const std::string>(property.second);
-              BMCWEB_LOG_DEBUG << "Host state: " << *s;
-              if (nullptr != s) {
-                const auto pos = s->rfind('.');
-                if (pos != std::string::npos) {
-                  // Verify Host State
-                  if (s->substr(pos + 1) == "Running") {
-                    aResp->res.jsonValue["PowerState"] = "On";
-                    aResp->res.jsonValue["Status"]["State"] = "Enabled";
-                  } else {
-                    aResp->res.jsonValue["PowerState"] = "Off";
-                    aResp->res.jsonValue["Status"]["State"] = "Disabled";
-                  }
+    template <typename CallbackFunc>
+    void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp,
+                        CallbackFunc &&callback)
+    {
+        BMCWEB_LOG_DEBUG << "Get identify led properties";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)},
+             &callback](const boost::system::error_code ec,
+                        const PropertiesType &properties) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
                 }
-              }
-            }
-          }
-        },
-        "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
-        "org.freedesktop.DBus.Properties", "GetAll",
-        "xyz.openbmc_project.State.Host");
-  }
+                BMCWEB_LOG_DEBUG << "Got " << properties.size()
+                                 << "led properties.";
+                std::string output;
+                for (const auto &property : properties)
+                {
+                    if (property.first == "State")
+                    {
+                        const std::string *s =
+                            mapbox::getPtr<std::string>(property.second);
+                        if (nullptr != s)
+                        {
+                            BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
+                            const auto pos = s->rfind('.');
+                            if (pos != std::string::npos)
+                            {
+                                auto led = s->substr(pos + 1);
+                                for (const std::pair<const char *, const char *>
+                                         &p :
+                                     std::array<
+                                         std::pair<const char *, const char *>,
+                                         3>{{{"On", "Lit"},
+                                             {"Blink", "Blinking"},
+                                             {"Off", "Off"}}})
+                                {
+                                    if (led == p.first)
+                                    {
+                                        output = p.second;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                callback(output, aResp);
+            },
+            "xyz.openbmc_project.LED.Controller.identify",
+            "/xyz/openbmc_project/led/physical/identify",
+            "org.freedesktop.DBus.Properties", "GetAll",
+            "xyz.openbmc_project.Led.Physical");
+    }
+
+    /**
+     * @brief Retrieves host state properties over dbus
+     *
+     * @param[in] aResp     Shared pointer for completing asynchronous calls.
+     *
+     * @return None.
+     */
+    void getHostState(std::shared_ptr<SystemAsyncResp> aResp)
+    {
+        BMCWEB_LOG_DEBUG << "Get host information.";
+        crow::connections::systemBus->async_method_call(
+            [aResp{std::move(aResp)}](const boost::system::error_code ec,
+                                      const PropertiesType &properties) {
+                if (ec)
+                {
+                    BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                    aResp->setErrorStatus();
+                    return;
+                }
+                BMCWEB_LOG_DEBUG << "Got " << properties.size()
+                                 << "host properties.";
+                for (const auto &property : properties)
+                {
+                    if (property.first == "CurrentHostState")
+                    {
+                        const std::string *s =
+                            mapbox::getPtr<const std::string>(property.second);
+                        BMCWEB_LOG_DEBUG << "Host state: " << *s;
+                        if (nullptr != s)
+                        {
+                            const auto pos = s->rfind('.');
+                            if (pos != std::string::npos)
+                            {
+                                // Verify Host State
+                                if (s->substr(pos + 1) == "Running")
+                                {
+                                    aResp->res.jsonValue["PowerState"] = "On";
+                                    aResp->res.jsonValue["Status"]["State"] =
+                                        "Enabled";
+                                }
+                                else
+                                {
+                                    aResp->res.jsonValue["PowerState"] = "Off";
+                                    aResp->res.jsonValue["Status"]["State"] =
+                                        "Disabled";
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "xyz.openbmc_project.State.Host",
+            "/xyz/openbmc_project/state/host0",
+            "org.freedesktop.DBus.Properties", "GetAll",
+            "xyz.openbmc_project.State.Host");
+    }
 };
 
 /**
  * SystemsCollection derived class for delivering ComputerSystems Collection
  * Schema
  */
-class SystemsCollection : public Node {
- public:
-  SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/") {
-    Node::json["@odata.type"] =
-        "#ComputerSystemCollection.ComputerSystemCollection";
-    Node::json["@odata.id"] = "/redfish/v1/Systems";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#ComputerSystemCollection.ComputerSystemCollection";
-    Node::json["Name"] = "Computer System Collection";
+class SystemsCollection : public Node
+{
+  public:
+    SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
+    {
+        Node::json["@odata.type"] =
+            "#ComputerSystemCollection.ComputerSystemCollection";
+        Node::json["@odata.id"] = "/redfish/v1/Systems";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#ComputerSystemCollection.ComputerSystemCollection";
+        Node::json["Name"] = "Computer System Collection";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
 
- private:
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Get board list, and call the below callback for JSON preparation
-    provider.getBaseboardList(
-        [&](const bool &success, const std::vector<std::string> &output) {
-          if (success) {
-            // ... prepare json array with appropriate @odata.id links
-            nlohmann::json boardArray = nlohmann::json::array();
-            for (const std::string &boardItem : output) {
-              boardArray.push_back(
-                  {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
+  private:
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Get board list, and call the below callback for JSON preparation
+        provider.getBaseboardList([&](const bool &success,
+                                      const std::vector<std::string> &output) {
+            if (success)
+            {
+                // ... prepare json array with appropriate @odata.id links
+                nlohmann::json boardArray = nlohmann::json::array();
+                for (const std::string &boardItem : output)
+                {
+                    boardArray.push_back(
+                        {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
+                }
+                // Then attach members, count size and return,
+                Node::json["Members"] = boardArray;
+                Node::json["Members@odata.count"] = boardArray.size();
+                res.jsonValue = Node::json;
             }
-            // Then attach members, count size and return,
-            Node::json["Members"] = boardArray;
-            Node::json["Members@odata.count"] = boardArray.size();
-            res.jsonValue = Node::json;
-          } else {
-            // ... otherwise, return INTERNALL ERROR
-            res.result(boost::beast::http::status::internal_server_error);
-          }
-          res.end();
+            else
+            {
+                // ... otherwise, return INTERNALL ERROR
+                res.result(boost::beast::http::status::internal_server_error);
+            }
+            res.end();
         });
-  }
+    }
 
-  OnDemandSystemsProvider provider;
+    OnDemandSystemsProvider provider;
 };
 
 /**
  * Systems override class for delivering ComputerSystems Schema
  */
-class Systems : public Node {
- public:
-  /*
-   * Default Constructor
-   */
-  Systems(CrowApp &app)
-      : Node(app, "/redfish/v1/Systems/<str>/", std::string()) {
-    Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
-    Node::json["SystemType"] = "Physical";
-    Node::json["Description"] = "Computer System";
-    Node::json["Boot"]["BootSourceOverrideEnabled"] =
-        "Disabled";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideTarget"] =
-        "None";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideMode"] =
-        "Legacy";  // TODO(Dawid), get real boot data
-    Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
-        "None",      "Pxe",       "Hdd", "Cd",
-        "BiosSetup", "UefiShell", "Usb"};  // TODO(Dawid), get real boot data
-    Node::json["ProcessorSummary"]["Count"] = int(0);
-    Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
-    Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
-    Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
+class Systems : public Node
+{
+  public:
+    /*
+     * Default Constructor
+     */
+    Systems(CrowApp &app) :
+        Node(app, "/redfish/v1/Systems/<str>/", std::string())
+    {
+        Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
+        Node::json["SystemType"] = "Physical";
+        Node::json["Description"] = "Computer System";
+        Node::json["Boot"]["BootSourceOverrideEnabled"] =
+            "Disabled"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideTarget"] =
+            "None"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideMode"] =
+            "Legacy"; // TODO(Dawid), get real boot data
+        Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
+            {"None",      "Pxe",       "Hdd", "Cd",
+             "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
+                                               // data
+        Node::json["ProcessorSummary"]["Count"] = int(0);
+        Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
+        Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
+        Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  OnDemandSystemsProvider provider;
-
-  /**
-   * Functions triggers appropriate requests on DBus
-   */
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    const std::string &name = params[0];
+  private:
+    OnDemandSystemsProvider provider;
 
-    res.jsonValue = Node::json;
-    res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
+    /**
+     * Functions triggers appropriate requests on DBus
+     */
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
 
-    auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+        const std::string &name = params[0];
 
-    provider.getLedGroupIdentify(
-        asyncResp, [&](const bool &asserted,
-                       const std::shared_ptr<SystemAsyncResp> &aResp) {
-          if (asserted) {
-            // If led group is asserted, then another call is needed to
-            // get led status
-            provider.getLedIdentify(
-                aResp, [](const std::string &ledStatus,
-                          const std::shared_ptr<SystemAsyncResp> &aResp) {
-                  if (!ledStatus.empty()) {
-                    aResp->res.jsonValue["IndicatorLED"] = ledStatus;
-                  }
-                });
-          } else {
-            aResp->res.jsonValue["IndicatorLED"] = "Off";
-          }
-        });
-    provider.getComputerSystem(asyncResp, name);
-    provider.getHostState(asyncResp);
-  }
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
 
-  void doPatch(crow::Response &res, const crow::Request &req,
-               const std::vector<std::string> &params) override {
-    // Check if there is required param, truly entering this shall be
-    // impossible
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
-    }
-    // Parse JSON request body
-    nlohmann::json patch;
-    if (!json_util::processJsonFromRequest(res, req, patch)) {
-      return;
-    }
-    // Find key with new led value
-    const std::string &name = params[0];
-    const std::string *reqLedState = nullptr;
-    json_util::Result r = json_util::getString(
-        "IndicatorLED", patch, reqLedState,
-        static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
-            static_cast<int>(json_util::MessageSetting::MISSING),
-        res.jsonValue, std::string("/" + name + "/IndicatorLED"));
-    if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr)) {
-      res.result(boost::beast::http::status::bad_request);
-      res.end();
-      return;
-    }
-    // Verify key value
-    std::string dbusLedState;
-    for (const auto &p : boost::container::flat_map<const char *, const char *>{
-             {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}}) {
-      if (*reqLedState == p.second) {
-        dbusLedState = p.first;
-      }
+        auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+
+        provider.getLedGroupIdentify(
+            asyncResp, [&](const bool &asserted,
+                           const std::shared_ptr<SystemAsyncResp> &aResp) {
+                if (asserted)
+                {
+                    // If led group is asserted, then another call is needed to
+                    // get led status
+                    provider.getLedIdentify(
+                        aResp,
+                        [](const std::string &ledStatus,
+                           const std::shared_ptr<SystemAsyncResp> &aResp) {
+                            if (!ledStatus.empty())
+                            {
+                                aResp->res.jsonValue["IndicatorLED"] =
+                                    ledStatus;
+                            }
+                        });
+                }
+                else
+                {
+                    aResp->res.jsonValue["IndicatorLED"] = "Off";
+                }
+            });
+        provider.getComputerSystem(asyncResp, name);
+        provider.getHostState(asyncResp);
     }
 
-    // Update led status
-    auto asyncResp = std::make_shared<SystemAsyncResp>(res);
-    res.jsonValue = Node::json;
-    res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
-
-    provider.getHostState(asyncResp);
-    provider.getComputerSystem(asyncResp, name);
-
-    if (dbusLedState.empty()) {
-      messages::addMessageToJsonRoot(
-          res.jsonValue,
-          messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
-    } else {
-      // Update led group
-      BMCWEB_LOG_DEBUG << "Update led group.";
-      crow::connections::systemBus->async_method_call(
-          [&, asyncResp{std::move(asyncResp)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-              asyncResp->setErrorStatus();
-              return;
+    void doPatch(crow::Response &res, const crow::Request &req,
+                 const std::vector<std::string> &params) override
+    {
+        // Check if there is required param, truly entering this shall be
+        // impossible
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        // Parse JSON request body
+        nlohmann::json patch;
+        if (!json_util::processJsonFromRequest(res, req, patch))
+        {
+            return;
+        }
+        // Find key with new led value
+        const std::string &name = params[0];
+        const std::string *reqLedState = nullptr;
+        json_util::Result r = json_util::getString(
+            "IndicatorLED", patch, reqLedState,
+            static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
+                static_cast<int>(json_util::MessageSetting::MISSING),
+            res.jsonValue, std::string("/" + name + "/IndicatorLED"));
+        if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr))
+        {
+            res.result(boost::beast::http::status::bad_request);
+            res.end();
+            return;
+        }
+        // Verify key value
+        std::string dbusLedState;
+        for (const auto &p :
+             boost::container::flat_map<const char *, const char *>{
+                 {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}})
+        {
+            if (*reqLedState == p.second)
+            {
+                dbusLedState = p.first;
             }
-            BMCWEB_LOG_DEBUG << "Led group update done.";
-          },
-          "xyz.openbmc_project.LED.GroupManager",
-          "/xyz/openbmc_project/led/groups/enclosure_identify",
-          "org.freedesktop.DBus.Properties", "Set",
-          "xyz.openbmc_project.Led.Group", "Asserted",
-          sdbusplus::message::variant<bool>(
-              (dbusLedState == "Off" ? false : true)));
-      // Update identify led status
-      BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
-      crow::connections::systemBus->async_method_call(
-          [&, asyncResp{std::move(asyncResp)} ](
-              const boost::system::error_code ec) {
-            if (ec) {
-              BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
-              asyncResp->setErrorStatus();
-              return;
-            }
-            BMCWEB_LOG_DEBUG << "Led state update done.";
-            res.jsonValue["IndicatorLED"] = *reqLedState;
-          },
-          "xyz.openbmc_project.LED.Controller.identify",
-          "/xyz/openbmc_project/led/physical/identify",
-          "org.freedesktop.DBus.Properties", "Set",
-          "xyz.openbmc_project.Led.Physical", "State",
-          sdbusplus::message::variant<std::string>(
-              "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
+        }
+
+        // Update led status
+        auto asyncResp = std::make_shared<SystemAsyncResp>(res);
+        res.jsonValue = Node::json;
+        res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
+
+        provider.getHostState(asyncResp);
+        provider.getComputerSystem(asyncResp, name);
+
+        if (dbusLedState.empty())
+        {
+            messages::addMessageToJsonRoot(
+                res.jsonValue,
+                messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
+        }
+        else
+        {
+            // Update led group
+            BMCWEB_LOG_DEBUG << "Update led group.";
+            crow::connections::systemBus->async_method_call(
+                [&, asyncResp{std::move(asyncResp)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        asyncResp->setErrorStatus();
+                        return;
+                    }
+                    BMCWEB_LOG_DEBUG << "Led group update done.";
+                },
+                "xyz.openbmc_project.LED.GroupManager",
+                "/xyz/openbmc_project/led/groups/enclosure_identify",
+                "org.freedesktop.DBus.Properties", "Set",
+                "xyz.openbmc_project.Led.Group", "Asserted",
+                sdbusplus::message::variant<bool>(
+                    (dbusLedState == "Off" ? false : true)));
+            // Update identify led status
+            BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
+            crow::connections::systemBus->async_method_call(
+                [&, asyncResp{std::move(asyncResp)}](
+                    const boost::system::error_code ec) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+                        asyncResp->setErrorStatus();
+                        return;
+                    }
+                    BMCWEB_LOG_DEBUG << "Led state update done.";
+                    res.jsonValue["IndicatorLED"] = *reqLedState;
+                },
+                "xyz.openbmc_project.LED.Controller.identify",
+                "/xyz/openbmc_project/led/physical/identify",
+                "org.freedesktop.DBus.Properties", "Set",
+                "xyz.openbmc_project.Led.Physical", "State",
+                sdbusplus::message::variant<std::string>(
+                    "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
+        }
     }
-  }
 };
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/thermal.hpp b/redfish-core/lib/thermal.hpp
index 8fb291b..37b0f43 100644
--- a/redfish-core/lib/thermal.hpp
+++ b/redfish-core/lib/thermal.hpp
@@ -18,44 +18,49 @@
 #include "node.hpp"
 #include "sensors.hpp"
 
-namespace redfish {
+namespace redfish
+{
 
-class Thermal : public Node {
- public:
-  Thermal(CrowApp& app)
-      : Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string()) {
-    Node::json["@odata.type"] = "#Thermal.v1_4_0.Thermal";
-    Node::json["@odata.context"] = "/redfish/v1/$metadata#Thermal.Thermal";
-    Node::json["Id"] = "Thermal";
-    Node::json["Name"] = "Thermal";
+class Thermal : public Node
+{
+  public:
+    Thermal(CrowApp& app) :
+        Node((app), "/redfish/v1/Chassis/<str>/Thermal/", std::string())
+    {
+        Node::json["@odata.type"] = "#Thermal.v1_4_0.Thermal";
+        Node::json["@odata.context"] = "/redfish/v1/$metadata#Thermal.Thermal";
+        Node::json["Id"] = "Thermal";
+        Node::json["Name"] = "Thermal";
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::put, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
-        {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
-  }
-
- private:
-  void doGet(crow::Response& res, const crow::Request& req,
-             const std::vector<std::string>& params) override {
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::put, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
+            {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
     }
-    const std::string& chassisName = params[0];
 
-    res.jsonValue = Node::json;
-    auto asyncResp = std::make_shared<SensorsAsyncResp>(
-        res, chassisName,
-        std::initializer_list<const char*>{
-            "/xyz/openbmc_project/sensors/fan",
-            "/xyz/openbmc_project/sensors/temperature"});
-    getChassisData(asyncResp);
-  }
+  private:
+    void doGet(crow::Response& res, const crow::Request& req,
+               const std::vector<std::string>& params) override
+    {
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.end();
+            return;
+        }
+        const std::string& chassisName = params[0];
+
+        res.jsonValue = Node::json;
+        auto asyncResp = std::make_shared<SensorsAsyncResp>(
+            res, chassisName,
+            std::initializer_list<const char*>{
+                "/xyz/openbmc_project/sensors/fan",
+                "/xyz/openbmc_project/sensors/temperature"});
+        getChassisData(asyncResp);
+    }
 };
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 677b6d1..658937d 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -16,381 +16,450 @@
 #pragma once
 
 #include "node.hpp"
+
 #include <boost/container/flat_map.hpp>
 
-namespace redfish {
+namespace redfish
+{
 static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
 
-class UpdateService : public Node {
- public:
-  UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") {
-    Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService";
-    Node::json["@odata.id"] = "/redfish/v1/UpdateService";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#UpdateService.UpdateService";
-    Node::json["Id"] = "UpdateService";
-    Node::json["Description"] = "Service for Software Update";
-    Node::json["Name"] = "Update Service";
-    Node::json["HttpPushUri"] = "/redfish/v1/UpdateService";
-    // UpdateService cannot be disabled
-    Node::json["ServiceEnabled"] = true;
-    Node::json["FirmwareInventory"] = {
-        {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
+class UpdateService : public Node
+{
+  public:
+    UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/")
+    {
+        Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService";
+        Node::json["@odata.id"] = "/redfish/v1/UpdateService";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#UpdateService.UpdateService";
+        Node::json["Id"] = "UpdateService";
+        Node::json["Description"] = "Service for Software Update";
+        Node::json["Name"] = "Update Service";
+        Node::json["HttpPushUri"] = "/redfish/v1/UpdateService";
+        // UpdateService cannot be disabled
+        Node::json["ServiceEnabled"] = true;
+        Node::json["FirmwareInventory"] = {
+            {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
 
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    res.jsonValue = Node::json;
-    res.end();
-  }
-  static void activateImage(const std::string &objPath) {
-    crow::connections::systemBus->async_method_call(
-        [objPath](const boost::system::error_code error_code) {
-          if (error_code) {
-            BMCWEB_LOG_DEBUG << "error_code = " << error_code;
-            BMCWEB_LOG_DEBUG << "error msg = " << error_code.message();
-          }
-        },
-        "xyz.openbmc_project.Software.BMC.Updater", objPath,
-        "org.freedesktop.DBus.Properties", "Set",
-        "xyz.openbmc_project.Software.Activation", "RequestedActivation",
-        sdbusplus::message::variant<std::string>(
-            "xyz.openbmc_project.Software.Activation.RequestedActivations."
-            "Active"));
-  }
-  void doPost(crow::Response &res, const crow::Request &req,
-              const std::vector<std::string> &params) override {
-    BMCWEB_LOG_DEBUG << "doPost...";
-
-    // Only allow one FW update at a time
-    if (fwUpdateMatcher != nullptr) {
-      res.addHeader("Retry-After", "30");
-      res.result(boost::beast::http::status::service_unavailable);
-      res.jsonValue = messages::serviceTemporarilyUnavailable("3");
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
-    // Make this const static so it survives outside this method
-    static boost::asio::deadline_timer timeout(*req.ioService,
-                                               boost::posix_time::seconds(5));
 
-    timeout.expires_from_now(boost::posix_time::seconds(5));
-
-    timeout.async_wait([&res](const boost::system::error_code &ec) {
-      fwUpdateMatcher = nullptr;
-      if (ec == boost::asio::error::operation_aborted) {
-        // expected, we were canceled before the timer completed.
-        return;
-      }
-      BMCWEB_LOG_ERROR << "Timed out waiting for firmware object being created";
-      BMCWEB_LOG_ERROR << "FW image may has already been uploaded to server";
-      if (ec) {
-        BMCWEB_LOG_ERROR << "Async_wait failed" << ec;
-        return;
-      }
-
-      res.result(boost::beast::http::status::internal_server_error);
-      res.jsonValue = redfish::messages::internalError();
-      res.end();
-    });
-
-    auto callback = [&res](sdbusplus::message::message &m) {
-      BMCWEB_LOG_DEBUG << "Match fired";
-      bool flag = false;
-
-      if (m.is_method_error()) {
-        BMCWEB_LOG_DEBUG << "Dbus method error!!!";
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        res.jsonValue = Node::json;
         res.end();
-        return;
-      }
-      std::vector<std::pair<
-          std::string,
-          std::vector<std::pair<std::string,
-                                sdbusplus::message::variant<std::string>>>>>
-          interfaces_properties;
+    }
+    static void activateImage(const std::string &objPath)
+    {
+        crow::connections::systemBus->async_method_call(
+            [objPath](const boost::system::error_code error_code) {
+                if (error_code)
+                {
+                    BMCWEB_LOG_DEBUG << "error_code = " << error_code;
+                    BMCWEB_LOG_DEBUG << "error msg = " << error_code.message();
+                }
+            },
+            "xyz.openbmc_project.Software.BMC.Updater", objPath,
+            "org.freedesktop.DBus.Properties", "Set",
+            "xyz.openbmc_project.Software.Activation", "RequestedActivation",
+            sdbusplus::message::variant<std::string>(
+                "xyz.openbmc_project.Software.Activation.RequestedActivations."
+                "Active"));
+    }
+    void doPost(crow::Response &res, const crow::Request &req,
+                const std::vector<std::string> &params) override
+    {
+        BMCWEB_LOG_DEBUG << "doPost...";
 
-      sdbusplus::message::object_path objPath;
-
-      m.read(objPath, interfaces_properties);  // Read in the object path
-                                               // that was just created
-      // std::string str_objpath = objPath.str;  // keep a copy for
-      // constructing response message
-      BMCWEB_LOG_DEBUG << "obj path = " << objPath.str;  // str_objpath;
-      for (auto &interface : interfaces_properties) {
-        BMCWEB_LOG_DEBUG << "interface = " << interface.first;
-
-        if (interface.first == "xyz.openbmc_project.Software.Activation") {
-          // cancel timer only when xyz.openbmc_project.Software.Activation
-          // interface is added
-          boost::system::error_code ec;
-          timeout.cancel(ec);
-          if (ec) {
-            BMCWEB_LOG_ERROR << "error canceling timer " << ec;
-          }
-          UpdateService::activateImage(objPath.str);  // str_objpath);
-          res.jsonValue = redfish::messages::success();
-          BMCWEB_LOG_DEBUG << "ending response";
-          res.end();
-          fwUpdateMatcher = nullptr;
-        }
-      }
-    };
-
-    fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
-        *crow::connections::systemBus,
-        "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
-        "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
-        callback);
-
-    std::string filepath(
-        "/tmp/images/" +
-        boost::uuids::to_string(boost::uuids::random_generator()()));
-    BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
-    std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
-                                    std::ofstream::trunc);
-    out << req.body;
-    out.close();
-    BMCWEB_LOG_DEBUG << "file upload complete!!";
-  }
-};
-
-class SoftwareInventoryCollection : public Node {
- public:
-  template <typename CrowApp>
-  SoftwareInventoryCollection(CrowApp &app)
-      : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") {
-    Node::json["@odata.type"] =
-        "#SoftwareInventoryCollection.SoftwareInventoryCollection";
-    Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory";
-    Node::json["@odata.context"] =
-        "/redfish/v1/"
-        "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection";
-    Node::json["Name"] = "Software Inventory Collection";
-
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
-
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-    res.jsonValue = Node::json;
-
-    crow::connections::systemBus->async_method_call(
-        [asyncResp](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          if (ec) {
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
+        // Only allow one FW update at a time
+        if (fwUpdateMatcher != nullptr)
+        {
+            res.addHeader("Retry-After", "30");
+            res.result(boost::beast::http::status::service_unavailable);
+            res.jsonValue = messages::serviceTemporarilyUnavailable("3");
+            res.end();
             return;
-          }
-          asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
-          asyncResp->res.jsonValue["Members@odata.count"] = 0;
+        }
+        // Make this const static so it survives outside this method
+        static boost::asio::deadline_timer timeout(
+            *req.ioService, boost::posix_time::seconds(5));
 
-          for (auto &obj : subtree) {
-            const std::vector<std::pair<std::string, std::vector<std::string>>>
-                &connections = obj.second;
+        timeout.expires_from_now(boost::posix_time::seconds(5));
 
-            for (auto &conn : connections) {
-              const std::string &connectionName = conn.first;
-              BMCWEB_LOG_DEBUG << "connectionName = " << connectionName;
-              BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
-
-              crow::connections::systemBus->async_method_call(
-                  [asyncResp](const boost::system::error_code error_code,
-                              const VariantType &activation) {
-                    BMCWEB_LOG_DEBUG << "safe returned in lambda function";
-                    if (error_code) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-
-                    const std::string *sw_inv_purpose =
-                        mapbox::getPtr<const std::string>(activation);
-                    if (sw_inv_purpose == nullptr) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    std::size_t last_pos = sw_inv_purpose->rfind(".");
-                    if (last_pos == std::string::npos) {
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    nlohmann::json &members =
-                        asyncResp->res.jsonValue["Members"];
-                    members.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/UpdateService/FirmwareInventory/" +
-                              sw_inv_purpose->substr(last_pos + 1)}});
-                    asyncResp->res.jsonValue["Members@odata.count"] =
-                        members.size();
-                  },
-                  connectionName, obj.first, "org.freedesktop.DBus.Properties",
-                  "Get", "xyz.openbmc_project.Software.Activation",
-                  "Activation");
+        timeout.async_wait([&res](const boost::system::error_code &ec) {
+            fwUpdateMatcher = nullptr;
+            if (ec == boost::asio::error::operation_aborted)
+            {
+                // expected, we were canceled before the timer completed.
+                return;
             }
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/software", int32_t(1),
-        std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"});
-  }
+            BMCWEB_LOG_ERROR
+                << "Timed out waiting for firmware object being created";
+            BMCWEB_LOG_ERROR
+                << "FW image may has already been uploaded to server";
+            if (ec)
+            {
+                BMCWEB_LOG_ERROR << "Async_wait failed" << ec;
+                return;
+            }
+
+            res.result(boost::beast::http::status::internal_server_error);
+            res.jsonValue = redfish::messages::internalError();
+            res.end();
+        });
+
+        auto callback = [&res](sdbusplus::message::message &m) {
+            BMCWEB_LOG_DEBUG << "Match fired";
+            bool flag = false;
+
+            if (m.is_method_error())
+            {
+                BMCWEB_LOG_DEBUG << "Dbus method error!!!";
+                res.end();
+                return;
+            }
+            std::vector<std::pair<
+                std::string,
+                std::vector<std::pair<
+                    std::string, sdbusplus::message::variant<std::string>>>>>
+                interfaces_properties;
+
+            sdbusplus::message::object_path objPath;
+
+            m.read(objPath, interfaces_properties); // Read in the object path
+                                                    // that was just created
+            // std::string str_objpath = objPath.str;  // keep a copy for
+            // constructing response message
+            BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; // str_objpath;
+            for (auto &interface : interfaces_properties)
+            {
+                BMCWEB_LOG_DEBUG << "interface = " << interface.first;
+
+                if (interface.first ==
+                    "xyz.openbmc_project.Software.Activation")
+                {
+                    // cancel timer only when
+                    // xyz.openbmc_project.Software.Activation interface is
+                    // added
+                    boost::system::error_code ec;
+                    timeout.cancel(ec);
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "error canceling timer " << ec;
+                    }
+                    UpdateService::activateImage(objPath.str); // str_objpath);
+                    res.jsonValue = redfish::messages::success();
+                    BMCWEB_LOG_DEBUG << "ending response";
+                    res.end();
+                    fwUpdateMatcher = nullptr;
+                }
+            }
+        };
+
+        fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
+            *crow::connections::systemBus,
+            "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
+            "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
+            callback);
+
+        std::string filepath(
+            "/tmp/images/" +
+            boost::uuids::to_string(boost::uuids::random_generator()()));
+        BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
+        std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
+                                        std::ofstream::trunc);
+        out << req.body;
+        out.close();
+        BMCWEB_LOG_DEBUG << "file upload complete!!";
+    }
 };
 
-class SoftwareInventory : public Node {
- public:
-  template <typename CrowApp>
-  SoftwareInventory(CrowApp &app)
-      : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
-             std::string()) {
-    Node::json["@odata.type"] = "#SoftwareInventory.v1_1_0.SoftwareInventory";
-    Node::json["@odata.context"] =
-        "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory";
-    Node::json["Name"] = "Software Inventory";
-    Node::json["Updateable"] = false;
-    Node::json["Status"]["Health"] = "OK";
-    Node::json["Status"]["HealthRollup"] = "OK";
-    Node::json["Status"]["State"] = "Enabled";
-    entityPrivileges = {
-        {boost::beast::http::verb::get, {{"Login"}}},
-        {boost::beast::http::verb::head, {{"Login"}}},
-        {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-        {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-  }
+class SoftwareInventoryCollection : public Node
+{
+  public:
+    template <typename CrowApp>
+    SoftwareInventoryCollection(CrowApp &app) :
+        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/")
+    {
+        Node::json["@odata.type"] =
+            "#SoftwareInventoryCollection.SoftwareInventoryCollection";
+        Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory";
+        Node::json["@odata.context"] =
+            "/redfish/v1/"
+            "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection";
+        Node::json["Name"] = "Software Inventory Collection";
 
- private:
-  void doGet(crow::Response &res, const crow::Request &req,
-             const std::vector<std::string> &params) override {
-    std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
-    res.jsonValue = Node::json;
-
-    if (params.size() != 1) {
-      res.result(boost::beast::http::status::internal_server_error);
-      res.jsonValue = messages::internalError();
-      res.end();
-      return;
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
     }
 
-    std::shared_ptr<std::string> sw_id =
-        std::make_shared<std::string>(params[0]);
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+        res.jsonValue = Node::json;
 
-    res.jsonValue["@odata.id"] =
-        "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id;
-
-    crow::connections::systemBus->async_method_call(
-        [asyncResp, sw_id](
-            const boost::system::error_code ec,
-            const std::vector<std::pair<
-                std::string,
-                std::vector<std::pair<std::string, std::vector<std::string>>>>>
-                &subtree) {
-          BMCWEB_LOG_DEBUG << "doGet callback...";
-          if (ec) {
-            asyncResp->res.result(
-                boost::beast::http::status::internal_server_error);
-            return;
-          }
-
-          for (const std::pair<std::string,
-                               std::vector<std::pair<std::string,
-                                                     std::vector<std::string>>>>
-                   &obj : subtree) {
-            if (boost::ends_with(obj.first, *sw_id) != true) {
-              continue;
-            }
-
-            if (obj.second.size() <= 1) {
-              continue;
-            }
-
-            crow::connections::systemBus->async_method_call(
-                [asyncResp, sw_id](
-                    const boost::system::error_code error_code,
-                    const boost::container::flat_map<std::string, VariantType>
-                        &propertiesList) {
-                  if (error_code) {
+        crow::connections::systemBus->async_method_call(
+            [asyncResp](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                if (ec)
+                {
                     asyncResp->res.result(
                         boost::beast::http::status::internal_server_error);
                     return;
-                  }
-                  boost::container::flat_map<std::string,
-                                             VariantType>::const_iterator it =
-                      propertiesList.find("Purpose");
-                  if (it == propertiesList.end()) {
-                    BMCWEB_LOG_DEBUG << "Can't find property \"Purpose\"!";
-                    asyncResp->res.result(
-                        boost::beast::http::status::internal_server_error);
-                    return;
-                  }
-                  const std::string *sw_inv_purpose =
-                      mapbox::getPtr<const std::string>(it->second);
-                  if (sw_inv_purpose == nullptr) {
-                    BMCWEB_LOG_DEBUG << "wrong types for property\"Purpose\"!";
-                    asyncResp->res.result(
-                        boost::beast::http::status::internal_server_error);
-                    return;
-                  }
+                }
+                asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
+                asyncResp->res.jsonValue["Members@odata.count"] = 0;
 
-                  BMCWEB_LOG_DEBUG << "sw_inv_purpose = " << *sw_inv_purpose;
-                  if (boost::ends_with(*sw_inv_purpose, "." + *sw_id)) {
-                    it = propertiesList.find("Version");
-                    if (it == propertiesList.end()) {
-                      BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!";
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
+                for (auto &obj : subtree)
+                {
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>
+                        &connections = obj.second;
+
+                    for (auto &conn : connections)
+                    {
+                        const std::string &connectionName = conn.first;
+                        BMCWEB_LOG_DEBUG << "connectionName = "
+                                         << connectionName;
+                        BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp](
+                                const boost::system::error_code error_code,
+                                const VariantType &activation) {
+                                BMCWEB_LOG_DEBUG
+                                    << "safe returned in lambda function";
+                                if (error_code)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+
+                                const std::string *sw_inv_purpose =
+                                    mapbox::getPtr<const std::string>(
+                                        activation);
+                                if (sw_inv_purpose == nullptr)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                std::size_t last_pos =
+                                    sw_inv_purpose->rfind(".");
+                                if (last_pos == std::string::npos)
+                                {
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                nlohmann::json &members =
+                                    asyncResp->res.jsonValue["Members"];
+                                members.push_back(
+                                    {{"@odata.id", "/redfish/v1/UpdateService/"
+                                                   "FirmwareInventory/" +
+                                                       sw_inv_purpose->substr(
+                                                           last_pos + 1)}});
+                                asyncResp->res
+                                    .jsonValue["Members@odata.count"] =
+                                    members.size();
+                            },
+                            connectionName, obj.first,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "xyz.openbmc_project.Software.Activation",
+                            "Activation");
                     }
-
-                    const std::string *version =
-                        mapbox::getPtr<const std::string>(it->second);
-
-                    if (version != nullptr) {
-                      BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!";
-                      asyncResp->res.result(
-                          boost::beast::http::status::internal_server_error);
-                      return;
-                    }
-                    asyncResp->res.jsonValue["Version"] = *version;
-                    asyncResp->res.jsonValue["Id"] = *sw_id;
-                  }
-                },
-                obj.second[0].first, obj.first,
-                "org.freedesktop.DBus.Properties", "GetAll",
-                "xyz.openbmc_project.Software.Version");
-          }
-        },
-        "xyz.openbmc_project.ObjectMapper",
-        "/xyz/openbmc_project/object_mapper",
-        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-        "/xyz/openbmc_project/software", int32_t(1),
-        std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"});
-  }
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/software", int32_t(1),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Software.Version"});
+    }
 };
 
-}  // namespace redfish
+class SoftwareInventory : public Node
+{
+  public:
+    template <typename CrowApp>
+    SoftwareInventory(CrowApp &app) :
+        Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
+             std::string())
+    {
+        Node::json["@odata.type"] =
+            "#SoftwareInventory.v1_1_0.SoftwareInventory";
+        Node::json["@odata.context"] =
+            "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory";
+        Node::json["Name"] = "Software Inventory";
+        Node::json["Updateable"] = false;
+        Node::json["Status"]["Health"] = "OK";
+        Node::json["Status"]["HealthRollup"] = "OK";
+        Node::json["Status"]["State"] = "Enabled";
+        entityPrivileges = {
+            {boost::beast::http::verb::get, {{"Login"}}},
+            {boost::beast::http::verb::head, {{"Login"}}},
+            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+    }
+
+  private:
+    void doGet(crow::Response &res, const crow::Request &req,
+               const std::vector<std::string> &params) override
+    {
+        std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
+        res.jsonValue = Node::json;
+
+        if (params.size() != 1)
+        {
+            res.result(boost::beast::http::status::internal_server_error);
+            res.jsonValue = messages::internalError();
+            res.end();
+            return;
+        }
+
+        std::shared_ptr<std::string> sw_id =
+            std::make_shared<std::string>(params[0]);
+
+        res.jsonValue["@odata.id"] =
+            "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id;
+
+        crow::connections::systemBus->async_method_call(
+            [asyncResp, sw_id](
+                const boost::system::error_code ec,
+                const std::vector<std::pair<
+                    std::string, std::vector<std::pair<
+                                     std::string, std::vector<std::string>>>>>
+                    &subtree) {
+                BMCWEB_LOG_DEBUG << "doGet callback...";
+                if (ec)
+                {
+                    asyncResp->res.result(
+                        boost::beast::http::status::internal_server_error);
+                    return;
+                }
+
+                for (const std::pair<
+                         std::string,
+                         std::vector<
+                             std::pair<std::string, std::vector<std::string>>>>
+                         &obj : subtree)
+                {
+                    if (boost::ends_with(obj.first, *sw_id) != true)
+                    {
+                        continue;
+                    }
+
+                    if (obj.second.size() <= 1)
+                    {
+                        continue;
+                    }
+
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp,
+                         sw_id](const boost::system::error_code error_code,
+                                const boost::container::flat_map<
+                                    std::string, VariantType> &propertiesList) {
+                            if (error_code)
+                            {
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            boost::container::flat_map<
+                                std::string, VariantType>::const_iterator it =
+                                propertiesList.find("Purpose");
+                            if (it == propertiesList.end())
+                            {
+                                BMCWEB_LOG_DEBUG
+                                    << "Can't find property \"Purpose\"!";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+                            const std::string *sw_inv_purpose =
+                                mapbox::getPtr<const std::string>(it->second);
+                            if (sw_inv_purpose == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG
+                                    << "wrong types for property\"Purpose\"!";
+                                asyncResp->res.result(
+                                    boost::beast::http::status::
+                                        internal_server_error);
+                                return;
+                            }
+
+                            BMCWEB_LOG_DEBUG << "sw_inv_purpose = "
+                                             << *sw_inv_purpose;
+                            if (boost::ends_with(*sw_inv_purpose, "." + *sw_id))
+                            {
+                                it = propertiesList.find("Version");
+                                if (it == propertiesList.end())
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+
+                                const std::string *version =
+                                    mapbox::getPtr<const std::string>(
+                                        it->second);
+
+                                if (version != nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Can't find property \"Version\"!";
+                                    asyncResp->res.result(
+                                        boost::beast::http::status::
+                                            internal_server_error);
+                                    return;
+                                }
+                                asyncResp->res.jsonValue["Version"] = *version;
+                                asyncResp->res.jsonValue["Id"] = *sw_id;
+                            }
+                        },
+                        obj.second[0].first, obj.first,
+                        "org.freedesktop.DBus.Properties", "GetAll",
+                        "xyz.openbmc_project.Software.Version");
+                }
+            },
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+            "/xyz/openbmc_project/software", int32_t(1),
+            std::array<const char *, 1>{
+                "xyz.openbmc_project.Software.Version"});
+    }
+};
+
+} // namespace redfish
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 4773e3d..a807762 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -13,78 +13,93 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 */
-#include <error_messages.hpp>
 #include <crow/logging.h>
 
-namespace redfish {
+#include <error_messages.hpp>
 
-namespace messages {
+namespace redfish
+{
+
+namespace messages
+{
 
 void addMessageToErrorJson(nlohmann::json& target,
-                           const nlohmann::json& message) {
-  auto& error = target["error"];
+                           const nlohmann::json& message)
+{
+    auto& error = target["error"];
 
-  // If this is the first error message, fill in the information from the first
-  // error message to the top level struct
-  if (!error.is_object()) {
-    auto message_id_iterator = message.find("MessageId");
-    if (message_id_iterator == message.end()) {
-      BMCWEB_LOG_CRITICAL << "Attempt to add error message without MessageId";
-      return;
-    }
+    // If this is the first error message, fill in the information from the
+    // first error message to the top level struct
+    if (!error.is_object())
+    {
+        auto message_id_iterator = message.find("MessageId");
+        if (message_id_iterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL
+                << "Attempt to add error message without MessageId";
+            return;
+        }
 
-    auto message_field_iterator = message.find("Message");
-    if (message_field_iterator == message.end()) {
-      BMCWEB_LOG_CRITICAL << "Attempt to add error message without Message";
-      return;
-    }
-    // clang-format off
+        auto message_field_iterator = message.find("Message");
+        if (message_field_iterator == message.end())
+        {
+            BMCWEB_LOG_CRITICAL
+                << "Attempt to add error message without Message";
+            return;
+        }
+        // clang-format off
     error = {
         {"code", *message_id_iterator},
         {"message", *message_field_iterator}
     };
-    // clang-format on
-  } else {
-    // More than 1 error occurred, so the message has to be generic
-    error["code"] = std::string(messageVersionPrefix) + "GeneralError";
-    error["message"] =
-        "A general error has occurred. See ExtendedInfo for more"
-        "information.";
-  }
+        // clang-format on
+    }
+    else
+    {
+        // More than 1 error occurred, so the message has to be generic
+        error["code"] = std::string(messageVersionPrefix) + "GeneralError";
+        error["message"] =
+            "A general error has occurred. See ExtendedInfo for more"
+            "information.";
+    }
 
-  // This check could technically be done in in the default construction
-  // branch above, but because we need the pointer to the extended info field
-  // anyway, it's more efficient to do it here.
-  auto& extended_info = error[messages::messageAnnotation];
-  if (!extended_info.is_array()) {
-    extended_info = nlohmann::json::array();
-  }
+    // This check could technically be done in in the default construction
+    // branch above, but because we need the pointer to the extended info field
+    // anyway, it's more efficient to do it here.
+    auto& extended_info = error[messages::messageAnnotation];
+    if (!extended_info.is_array())
+    {
+        extended_info = nlohmann::json::array();
+    }
 
-  extended_info.push_back(message);
+    extended_info.push_back(message);
 }
 
-void addMessageToJsonRoot(nlohmann::json& target,
-                          const nlohmann::json& message) {
-  if (!target[messages::messageAnnotation].is_array()) {
-    // Force object to be an array
-    target[messages::messageAnnotation] = nlohmann::json::array();
-  }
+void addMessageToJsonRoot(nlohmann::json& target, const nlohmann::json& message)
+{
+    if (!target[messages::messageAnnotation].is_array())
+    {
+        // Force object to be an array
+        target[messages::messageAnnotation] = nlohmann::json::array();
+    }
 
-  target[messages::messageAnnotation].push_back(message);
+    target[messages::messageAnnotation].push_back(message);
 }
 
 void addMessageToJson(nlohmann::json& target, const nlohmann::json& message,
-                      const std::string& fieldPath) {
-  nlohmann::json_pointer<nlohmann::json> extendedInfo(
-      fieldPath + messages::messageAnnotation);
+                      const std::string& fieldPath)
+{
+    nlohmann::json_pointer<nlohmann::json> extendedInfo(
+        fieldPath + messages::messageAnnotation);
 
-  if (!target[extendedInfo].is_array()) {
-    // Force object to be an array
-    target[extendedInfo] = nlohmann::json::array();
-  }
+    if (!target[extendedInfo].is_array())
+    {
+        // Force object to be an array
+        target[extendedInfo] = nlohmann::json::array();
+    }
 
-  // Object exists and it is an array so we can just push in the message
-  target[extendedInfo].push_back(message);
+    // Object exists and it is an array so we can just push in the message
+    target[extendedInfo].push_back(message);
 }
 
 /*********************************
@@ -98,17 +113,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceInUse() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceInUse"},
-      {"Message",
-       "The change to the requested resource failed because the resource is in "
-       "use or in transition."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the condition and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json resourceInUse()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceInUse"},
+        {"Message", "The change to the requested resource failed because the "
+                    "resource is in "
+                    "use or in transition."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the condition and resubmit the request if the operation "
+         "failed."}};
 }
 
 /**
@@ -118,16 +134,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json malformedJSON() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.MalformedJSON"},
-      {"Message",
-       "The request body submitted was malformed JSON and could not be parsed "
-       "by the receiving service."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the request body is valid JSON and resubmit the request."}};
+nlohmann::json malformedJSON()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.MalformedJSON"},
+        {"Message", "The request body submitted was malformed JSON and could "
+                    "not be parsed "
+                    "by the receiving service."},
+        {"Severity", "Critical"},
+        {"Resolution", "Ensure that the request body is valid JSON and "
+                       "resubmit the request."}};
 }
 
 /**
@@ -137,15 +154,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceMissingAtURI(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceMissingAtURI"},
-      {"Message", "The resource at the URI " + arg1 + " was not found."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Place a valid resource at the URI or correct the URI and resubmit the "
-       "request."}};
+nlohmann::json resourceMissingAtURI(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceMissingAtURI"},
+        {"Message", "The resource at the URI " + arg1 + " was not found."},
+        {"Severity", "Critical"},
+        {"Resolution", "Place a valid resource at the URI or correct the URI "
+                       "and resubmit the "
+                       "request."}};
 }
 
 /**
@@ -157,17 +175,19 @@
  */
 nlohmann::json actionParameterValueFormatError(const std::string& arg1,
                                                const std::string& arg2,
-                                               const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the parameter " + arg2 + " in the action " +
-           arg3 + " is of a different format than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the parameter in the request body and resubmit "
-       "the request if the operation failed."}};
+                                               const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " in the action " + arg3 +
+             " is of a different format than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the parameter in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -177,17 +197,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json internalError() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InternalError"},
-      {"Message",
-       "The request failed due to an internal service error.  The service is "
-       "still operational."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Resubmit the request.  If the problem persists, consider resetting the "
-       "service."}};
+nlohmann::json internalError()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InternalError"},
+        {"Message",
+         "The request failed due to an internal service error.  The service is "
+         "still operational."},
+        {"Severity", "Critical"},
+        {"Resolution", "Resubmit the request.  If the problem persists, "
+                       "consider resetting the "
+                       "service."}};
 }
 
 /**
@@ -197,16 +218,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json unrecognizedRequestBody() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.UnrecognizedRequestBody"},
-      {"Message",
-       "The service detected a malformed request body that it was unable to "
-       "interpret."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the request body and resubmit the request if it failed."}};
+nlohmann::json unrecognizedRequestBody()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.UnrecognizedRequestBody"},
+        {"Message",
+         "The service detected a malformed request body that it was unable to "
+         "interpret."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the request body and resubmit the request if it failed."}};
 }
 
 /**
@@ -217,17 +239,18 @@
  * @endinternal
  */
 nlohmann::json resourceAtUriUnauthorized(const std::string& arg1,
-                                         const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAtUriUnauthorized"},
-      {"Message", "While accessing the resource at " + arg1 +
-                      ", the service received an authorization error " + arg2 +
-                      "."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the appropriate access is provided for the service in "
-       "order for it to access the URI."}};
+                                         const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAtUriUnauthorized"},
+        {"Message", "While accessing the resource at " + arg1 +
+                        ", the service received an authorization error " +
+                        arg2 + "."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the appropriate access is provided for the service in "
+         "order for it to access the URI."}};
 }
 
 /**
@@ -238,17 +261,18 @@
  * @endinternal
  */
 nlohmann::json actionParameterUnknown(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterUnknown"},
-      {"Message", "The action " + arg1 +
-                      " was submitted with the invalid parameter " + arg2 +
-                      "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the invalid parameter and resubmit the request if the "
-       "operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterUnknown"},
+        {"Message", "The action " + arg1 +
+                        " was submitted with the invalid parameter " + arg2 +
+                        "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the invalid parameter and resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -258,15 +282,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceCannotBeDeleted() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceCannotBeDeleted"},
-      {"Message",
-       "The delete request failed because the resource requested cannot be "
-       "deleted."},
-      {"Severity", "Critical"},
-      {"Resolution", "Do not attempt to delete a non-deletable resource."}};
+nlohmann::json resourceCannotBeDeleted()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceCannotBeDeleted"},
+        {"Message",
+         "The delete request failed because the resource requested cannot be "
+         "deleted."},
+        {"Severity", "Critical"},
+        {"Resolution", "Do not attempt to delete a non-deletable resource."}};
 }
 
 /**
@@ -276,15 +301,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyDuplicate(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyDuplicate"},
-      {"Message", "The property " + arg1 + " was duplicated in the request."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the duplicate property from the request body and resubmit the "
-       "request if the operation failed."}};
+nlohmann::json propertyDuplicate(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyDuplicate"},
+        {"Message", "The property " + arg1 + " was duplicated in the request."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the duplicate property from the request body and resubmit the "
+         "request if the operation failed."}};
 }
 
 /**
@@ -294,15 +320,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceTemporarilyUnavailable(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceTemporarilyUnavailable"},
-      {"Message", "The service is temporarily unavailable.  Retry in " + arg1 +
-                      " seconds."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Wait for the indicated retry duration and retry the operation."}};
+nlohmann::json serviceTemporarilyUnavailable(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceTemporarilyUnavailable"},
+        {"Message", "The service is temporarily unavailable.  Retry in " +
+                        arg1 + " seconds."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Wait for the indicated retry duration and retry the operation."}};
 }
 
 /**
@@ -314,17 +341,18 @@
  */
 nlohmann::json resourceAlreadyExists(const std::string& arg1,
                                      const std::string& arg2,
-                                     const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAlreadyExists"},
-      {"Message", "The requested resource of type " + arg1 +
-                      " with the property " + arg2 + " with the value " + arg3 +
-                      " already exists."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Do not repeat the create operation as the resource has already been "
-       "created."}};
+                                     const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAlreadyExists"},
+        {"Message", "The requested resource of type " + arg1 +
+                        " with the property " + arg2 + " with the value " +
+                        arg3 + " already exists."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Do not repeat the create operation as the resource has already been "
+         "created."}};
 }
 
 /**
@@ -334,15 +362,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountForSessionNoLongerExists() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountForSessionNoLongerExists"},
-      {"Message",
-       "The account for the current session has been removed, thus the current "
-       "session has been removed as well."},
-      {"Severity", "OK"},
-      {"Resolution", "Attempt to connect with a valid account."}};
+nlohmann::json accountForSessionNoLongerExists()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountForSessionNoLongerExists"},
+        {"Message", "The account for the current session has been removed, "
+                    "thus the current "
+                    "session has been removed as well."},
+        {"Severity", "OK"},
+        {"Resolution", "Attempt to connect with a valid account."}};
 }
 
 /**
@@ -352,16 +381,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json createFailedMissingReqProperties(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CreateFailedMissingReqProperties"},
-      {"Message", "The create operation failed because the required property " +
-                      arg1 + " was missing from the request."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Correct the body to include the required property with a valid value "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json createFailedMissingReqProperties(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CreateFailedMissingReqProperties"},
+        {"Message",
+         "The create operation failed because the required property " + arg1 +
+             " was missing from the request."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Correct the body to include the required property with a valid value "
+         "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -372,17 +403,18 @@
  * @endinternal
  */
 nlohmann::json propertyValueFormatError(const std::string& arg1,
-                                        const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the property " + arg2 +
-           " is of a different format than the property can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the property in the request body and resubmit "
-       "the request if the operation failed."}};
+                                        const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the property " + arg2 +
+             " is of a different format than the property can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the property in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -393,16 +425,17 @@
  * @endinternal
  */
 nlohmann::json propertyValueNotInList(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueNotInList"},
-      {"Message", "The value " + arg1 + " for the property " + arg2 +
-                      " is not in the list of acceptable values."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Choose a value from the enumeration list that the implementation can "
-       "support and resubmit the request if the operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueNotInList"},
+        {"Message", "The value " + arg1 + " for the property " + arg2 +
+                        " is not in the list of acceptable values."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Choose a value from the enumeration list that the implementation can "
+         "support and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -412,16 +445,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceAtUriInUnknownFormat(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceAtUriInUnknownFormat"},
-      {"Message", "The resource at " + arg1 +
-                      " is in a format not recognized by the service."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Place an image or resource or file that is recognized by the service "
-       "at the URI."}};
+nlohmann::json resourceAtUriInUnknownFormat(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceAtUriInUnknownFormat"},
+        {"Message", "The resource at " + arg1 +
+                        " is in a format not recognized by the service."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Place an image or resource or file that is recognized by the service "
+         "at the URI."}};
 }
 
 /**
@@ -431,17 +465,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceInUnknownState() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceInUnknownState"},
-      {"Message",
-       "The operation failed because the service is in an unknown state and "
-       "can no longer take incoming requests."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Restart the service and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json serviceInUnknownState()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceInUnknownState"},
+        {"Message",
+         "The operation failed because the service is in an unknown state and "
+         "can no longer take incoming requests."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Restart the service and resubmit the request if the operation "
+         "failed."}};
 }
 
 /**
@@ -451,18 +486,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json eventSubscriptionLimitExceeded() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.EventSubscriptionLimitExceeded"},
-      {"Message",
-       "The event subscription failed due to the number of simultaneous "
-       "subscriptions exceeding the limit of the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Reduce the number of other subscriptions before trying to establish "
-       "the event subscription or increase the limit of simultaneous "
-       "subscriptions (if supported)."}};
+nlohmann::json eventSubscriptionLimitExceeded()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.EventSubscriptionLimitExceeded"},
+        {"Message",
+         "The event subscription failed due to the number of simultaneous "
+         "subscriptions exceeding the limit of the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Reduce the number of other subscriptions before trying to establish "
+         "the event subscription or increase the limit of simultaneous "
+         "subscriptions (if supported)."}};
 }
 
 /**
@@ -473,16 +509,17 @@
  * @endinternal
  */
 nlohmann::json actionParameterMissing(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterMissing"},
-      {"Message", "The action " + arg1 + " requires the parameter " + arg2 +
-                      " to be present in the request body."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Supply the action with the required parameter in the request body when "
-       "the request is resubmitted."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterMissing"},
+        {"Message", "The action " + arg1 + " requires the parameter " + arg2 +
+                        " to be present in the request body."},
+        {"Severity", "Critical"},
+        {"Resolution", "Supply the action with the required parameter in the "
+                       "request body when "
+                       "the request is resubmitted."}};
 }
 
 /**
@@ -492,15 +529,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json stringValueTooLong(const std::string& arg1, const int& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.StringValueTooLong"},
-      {"Message", "The string " + arg1 + " exceeds the length limit " +
-                      std::to_string(arg2) + "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Resubmit the request with an appropriate string length."}};
+nlohmann::json stringValueTooLong(const std::string& arg1, const int& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.StringValueTooLong"},
+        {"Message", "The string " + arg1 + " exceeds the length limit " +
+                        std::to_string(arg2) + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Resubmit the request with an appropriate string length."}};
 }
 
 /**
@@ -511,16 +549,18 @@
  * @endinternal
  */
 nlohmann::json propertyValueTypeError(const std::string& arg1,
-                                      const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueTypeError"},
-      {"Message", "The value " + arg1 + " for the property " + arg2 +
-                      " is of a different type than the property can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the property in the request body and resubmit "
-       "the request if the operation failed."}};
+                                      const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the property " + arg2 +
+             " is of a different type than the property can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the property in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -531,15 +571,16 @@
  * @endinternal
  */
 nlohmann::json resourceNotFound(const std::string& arg1,
-                                const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceNotFound"},
-      {"Message", "The requested resource of type " + arg1 + " named " + arg2 +
-                      " was not found."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Provide a valid resource identifier and resubmit the request."}};
+                                const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceNotFound"},
+        {"Message", "The requested resource of type " + arg1 + " named " +
+                        arg2 + " was not found."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Provide a valid resource identifier and resubmit the request."}};
 }
 
 /**
@@ -549,16 +590,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json couldNotEstablishConnection(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CouldNotEstablishConnection"},
-      {"Message", "The service failed to establish a Connection with the URI " +
-                      arg1 + "."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the URI contains a valid and reachable node name, protocol "
-       "information and other URI components."}};
+nlohmann::json couldNotEstablishConnection(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CouldNotEstablishConnection"},
+        {"Message",
+         "The service failed to establish a Connection with the URI " + arg1 +
+             "."},
+        {"Severity", "Critical"},
+        {"Resolution", "Ensure that the URI contains a valid and reachable "
+                       "node name, protocol "
+                       "information and other URI components."}};
 }
 
 /**
@@ -568,17 +611,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyNotWritable(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyNotWritable"},
-      {"Message",
-       "The property " + arg1 +
-           " is a read only property and cannot be assigned a value."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the property from the request body and resubmit the request if "
-       "the operation failed."}};
+nlohmann::json propertyNotWritable(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyNotWritable"},
+        {"Message",
+         "The property " + arg1 +
+             " is a read only property and cannot be assigned a value."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the property from the request body and resubmit "
+                       "the request if "
+                       "the operation failed."}};
 }
 
 /**
@@ -589,16 +633,18 @@
  * @endinternal
  */
 nlohmann::json queryParameterValueTypeError(const std::string& arg1,
-                                            const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterValueTypeError"},
-      {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
-                      " is of a different type than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the query parameter in the request and resubmit "
-       "the request if the operation failed."}};
+                                            const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the query parameter " + arg2 +
+             " is of a different type than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution", "Correct the value for the query parameter in the "
+                       "request and resubmit "
+                       "the request if the operation failed."}};
 }
 
 /**
@@ -608,17 +654,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json serviceShuttingDown() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ServiceShuttingDown"},
-      {"Message",
-       "The operation failed because the service is shutting down and can no "
-       "longer take incoming requests."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "When the service becomes available, resubmit the request if the "
-       "operation failed."}};
+nlohmann::json serviceShuttingDown()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ServiceShuttingDown"},
+        {"Message",
+         "The operation failed because the service is shutting down and can no "
+         "longer take incoming requests."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "When the service becomes available, resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -629,18 +676,19 @@
  * @endinternal
  */
 nlohmann::json actionParameterDuplicate(const std::string& arg1,
-                                        const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterDuplicate"},
-      {"Message",
-       "The action " + arg1 +
-           " was submitted with more than one value for the parameter " + arg2 +
-           "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Resubmit the action with only one instance of the parameter in the "
-       "request body if the operation failed."}};
+                                        const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterDuplicate"},
+        {"Message",
+         "The action " + arg1 +
+             " was submitted with more than one value for the parameter " +
+             arg2 + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Resubmit the action with only one instance of the parameter in the "
+         "request body if the operation failed."}};
 }
 
 /**
@@ -651,16 +699,17 @@
  * @endinternal
  */
 nlohmann::json actionParameterNotSupported(const std::string& arg1,
-                                           const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterNotSupported"},
-      {"Message", "The parameter " + arg1 + " for the action " + arg2 +
-                      " is not supported on the target resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the parameter supplied and resubmit the request if the "
-       "operation failed."}};
+                                           const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterNotSupported"},
+        {"Message", "The parameter " + arg1 + " for the action " + arg2 +
+                        " is not supported on the target resource."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the parameter supplied and resubmit the request if the "
+         "operation failed."}};
 }
 
 /**
@@ -671,14 +720,16 @@
  * @endinternal
  */
 nlohmann::json sourceDoesNotSupportProtocol(const std::string& arg1,
-                                            const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.SourceDoesNotSupportProtocol"},
-      {"Message", "The other end of the Connection at " + arg1 +
-                      " does not support the specified protocol " + arg2 + "."},
-      {"Severity", "Critical"},
-      {"Resolution", "Change protocols or URIs. "}};
+                                            const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.SourceDoesNotSupportProtocol"},
+        {"Message", "The other end of the Connection at " + arg1 +
+                        " does not support the specified protocol " + arg2 +
+                        "."},
+        {"Severity", "Critical"},
+        {"Resolution", "Change protocols or URIs. "}};
 }
 
 /**
@@ -688,13 +739,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountRemoved() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountRemoved"},
-      {"Message", "The account was successfully removed."},
-      {"Severity", "OK"},
-      {"Resolution", "No resolution is required."}};
+nlohmann::json accountRemoved()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountRemoved"},
+        {"Message", "The account was successfully removed."},
+        {"Severity", "OK"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -704,16 +756,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accessDenied(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccessDenied"},
-      {"Message", "While attempting to establish a Connection to " + arg1 +
-                      ", the service denied access."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Attempt to ensure that the URI is correct and that the service has the "
-       "appropriate credentials."}};
+nlohmann::json accessDenied(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccessDenied"},
+        {"Message", "While attempting to establish a Connection to " + arg1 +
+                        ", the service denied access."},
+        {"Severity", "Critical"},
+        {"Resolution", "Attempt to ensure that the URI is correct and that the "
+                       "service has the "
+                       "appropriate credentials."}};
 }
 
 /**
@@ -723,15 +776,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json queryNotSupported() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryNotSupported"},
-      {"Message", "Querying is not supported by the implementation."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the query parameters and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json queryNotSupported()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryNotSupported"},
+        {"Message", "Querying is not supported by the implementation."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the query parameters and resubmit the request "
+                       "if the operation "
+                       "failed."}};
 }
 
 /**
@@ -741,17 +795,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json createLimitReachedForResource() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.CreateLimitReachedForResource"},
-      {"Message",
-       "The create operation failed because the resource has reached the limit "
-       "of possible resources."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either delete resources and resubmit the request if the operation "
-       "failed or do not resubmit the request."}};
+nlohmann::json createLimitReachedForResource()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.CreateLimitReachedForResource"},
+        {"Message", "The create operation failed because the resource has "
+                    "reached the limit "
+                    "of possible resources."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Either delete resources and resubmit the request if the operation "
+         "failed or do not resubmit the request."}};
 }
 
 /**
@@ -761,14 +816,15 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json generalError() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.GeneralError"},
-      {"Message",
-       "A general error has occurred. See ExtendedInfo for more information."},
-      {"Severity", "Critical"},
-      {"Resolution", "See ExtendedInfo for more information."}};
+nlohmann::json generalError()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.GeneralError"},
+        {"Message", "A general error has occurred. See ExtendedInfo for more "
+                    "information."},
+        {"Severity", "Critical"},
+        {"Resolution", "See ExtendedInfo for more information."}};
 }
 
 /**
@@ -778,13 +834,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json success() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.Success"},
-      {"Message", "Successfully Completed Request"},
-      {"Severity", "OK"},
-      {"Resolution", "None"}};
+nlohmann::json success()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.Success"},
+        {"Message", "Successfully Completed Request"},
+        {"Severity", "OK"},
+        {"Resolution", "None"}};
 }
 
 /**
@@ -794,13 +851,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json created() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.Created"},
-      {"Message", "The resource has been created successfully"},
-      {"Severity", "OK"},
-      {"Resolution", "None"}};
+nlohmann::json created()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.Created"},
+        {"Message", "The resource has been created successfully"},
+        {"Severity", "OK"},
+        {"Resolution", "None"}};
 }
 
 /**
@@ -810,17 +868,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyUnknown(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyUnknown"},
-      {"Message",
-       "The property " + arg1 +
-           " is not in the list of valid properties for the resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the unknown property from the request body and resubmit the "
-       "request if the operation failed."}};
+nlohmann::json propertyUnknown(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyUnknown"},
+        {"Message",
+         "The property " + arg1 +
+             " is not in the list of valid properties for the resource."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Remove the unknown property from the request body and resubmit the "
+         "request if the operation failed."}};
 }
 
 /**
@@ -830,14 +889,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json noValidSession() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.NoValidSession"},
-      {"Message",
-       "There is no valid session established with the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution", "Establish as session before attempting any operations."}};
+nlohmann::json noValidSession()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.NoValidSession"},
+        {"Message",
+         "There is no valid session established with the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Establish as session before attempting any operations."}};
 }
 
 /**
@@ -847,15 +908,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json invalidObject(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InvalidObject"},
-      {"Message", "The object at " + arg1 + " is invalid."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either the object is malformed or the URI is not correct.  Correct the "
-       "condition and resubmit the request if it failed."}};
+nlohmann::json invalidObject(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InvalidObject"},
+        {"Message", "The object at " + arg1 + " is invalid."},
+        {"Severity", "Critical"},
+        {"Resolution", "Either the object is malformed or the URI is not "
+                       "correct.  Correct the "
+                       "condition and resubmit the request if it failed."}};
 }
 
 /**
@@ -865,17 +927,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceInStandby() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceInStandby"},
-      {"Message",
-       "The request could not be performed because the resource is in "
-       "standby."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the resource is in the correct power state and resubmit "
-       "the request."}};
+nlohmann::json resourceInStandby()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceInStandby"},
+        {"Message",
+         "The request could not be performed because the resource is in "
+         "standby."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the resource is in the correct power state and resubmit "
+         "the request."}};
 }
 
 /**
@@ -887,17 +950,19 @@
  */
 nlohmann::json actionParameterValueTypeError(const std::string& arg1,
                                              const std::string& arg2,
-                                             const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionParameterValueTypeError"},
-      {"Message", "The value " + arg1 + " for the parameter " + arg2 +
-                      " in the action " + arg3 +
-                      " is of a different type than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the parameter in the request body and resubmit "
-       "the request if the operation failed."}};
+                                             const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionParameterValueTypeError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " in the action " + arg3 +
+             " is of a different type than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Correct the value for the parameter in the request body and resubmit "
+         "the request if the operation failed."}};
 }
 
 /**
@@ -907,18 +972,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json sessionLimitExceeded() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.SessionLimitExceeded"},
-      {"Message",
-       "The session establishment failed due to the number of simultaneous "
-       "sessions exceeding the limit of the implementation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Reduce the number of other sessions before trying to establish the "
-       "session or increase the limit of simultaneous sessions (if "
-       "supported)."}};
+nlohmann::json sessionLimitExceeded()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.SessionLimitExceeded"},
+        {"Message",
+         "The session establishment failed due to the number of simultaneous "
+         "sessions exceeding the limit of the implementation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Reduce the number of other sessions before trying to establish the "
+         "session or increase the limit of simultaneous sessions (if "
+         "supported)."}};
 }
 
 /**
@@ -928,16 +994,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json actionNotSupported(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ActionNotSupported"},
-      {"Message", "The action " + arg1 + " is not supported by the resource."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "The action supplied cannot be resubmitted to the implementation.  "
-       "Perhaps the action was invalid, the wrong resource was the target or "
-       "the implementation documentation may be of assistance."}};
+nlohmann::json actionNotSupported(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ActionNotSupported"},
+        {"Message",
+         "The action " + arg1 + " is not supported by the resource."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "The action supplied cannot be resubmitted to the implementation.  "
+         "Perhaps the action was invalid, the wrong resource was the target or "
+         "the implementation documentation may be of assistance."}};
 }
 
 /**
@@ -947,15 +1015,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json invalidIndex(const int& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InvalidIndex"},
-      {"Message", "The index " + std::to_string(arg1) +
-                      " is not a valid offset into the array."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Verify the index value provided is within the bounds of the array."}};
+nlohmann::json invalidIndex(const int& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InvalidIndex"},
+        {"Message", "The index " + std::to_string(arg1) +
+                        " is not a valid offset into the array."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Verify the index value provided is within the bounds of the array."}};
 }
 
 /**
@@ -965,16 +1034,17 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json emptyJSON() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.EmptyJSON"},
-      {"Message",
-       "The request body submitted contained an empty JSON object and the "
-       "service is unable to process it."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Add properties in the JSON object and resubmit the request."}};
+nlohmann::json emptyJSON()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.EmptyJSON"},
+        {"Message",
+         "The request body submitted contained an empty JSON object and the "
+         "service is unable to process it."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Add properties in the JSON object and resubmit the request."}};
 }
 
 /**
@@ -984,15 +1054,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json queryNotSupportedOnResource() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryNotSupportedOnResource"},
-      {"Message", "Querying is not supported on the requested resource."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Remove the query parameters and resubmit the request if the operation "
-       "failed."}};
+nlohmann::json queryNotSupportedOnResource()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryNotSupportedOnResource"},
+        {"Message", "Querying is not supported on the requested resource."},
+        {"Severity", "Warning"},
+        {"Resolution", "Remove the query parameters and resubmit the request "
+                       "if the operation "
+                       "failed."}};
 }
 
 /**
@@ -1002,18 +1073,19 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json insufficientPrivilege() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.InsufficientPrivilege"},
-      {"Message",
-       "There are insufficient privileges for the account or credentials "
-       "associated with the current session to perform the requested "
-       "operation."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Either abandon the operation or change the associated access rights "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json insufficientPrivilege()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.InsufficientPrivilege"},
+        {"Message",
+         "There are insufficient privileges for the account or credentials "
+         "associated with the current session to perform the requested "
+         "operation."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Either abandon the operation or change the associated access rights "
+         "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -1024,14 +1096,15 @@
  * @endinternal
  */
 nlohmann::json propertyValueModified(const std::string& arg1,
-                                     const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyValueModified"},
-      {"Message", "The property " + arg1 + " was assigned the value " + arg2 +
-                      " due to modification by the service."},
-      {"Severity", "Warning"},
-      {"Resolution", "No resolution is required."}};
+                                     const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyValueModified"},
+        {"Message", "The property " + arg1 + " was assigned the value " + arg2 +
+                        " due to modification by the service."},
+        {"Severity", "Warning"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -1041,15 +1114,16 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountNotModified() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountNotModified"},
-      {"Message", "The account modification request failed."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "The modification may have failed due to permission issues or issues "
-       "with the request body."}};
+nlohmann::json accountNotModified()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountNotModified"},
+        {"Message", "The account modification request failed."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "The modification may have failed due to permission issues or issues "
+         "with the request body."}};
 }
 
 /**
@@ -1060,17 +1134,18 @@
  * @endinternal
  */
 nlohmann::json queryParameterValueFormatError(const std::string& arg1,
-                                              const std::string& arg2) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterValueFormatError"},
-      {"Message",
-       "The value " + arg1 + " for the parameter " + arg2 +
-           " is of a different format than the parameter can accept."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Correct the value for the query parameter in the request and resubmit "
-       "the request if the operation failed."}};
+                                              const std::string& arg2)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterValueFormatError"},
+        {"Message",
+         "The value " + arg1 + " for the parameter " + arg2 +
+             " is of a different format than the parameter can accept."},
+        {"Severity", "Warning"},
+        {"Resolution", "Correct the value for the query parameter in the "
+                       "request and resubmit "
+                       "the request if the operation failed."}};
 }
 
 /**
@@ -1080,17 +1155,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json propertyMissing(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.PropertyMissing"},
-      {"Message",
-       "The property " + arg1 +
-           " is a required property and must be included in the request."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Ensure that the property is in the request body and has a valid value "
-       "and resubmit the request if the operation failed."}};
+nlohmann::json propertyMissing(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.PropertyMissing"},
+        {"Message",
+         "The property " + arg1 +
+             " is a required property and must be included in the request."},
+        {"Severity", "Warning"},
+        {"Resolution", "Ensure that the property is in the request body and "
+                       "has a valid value "
+                       "and resubmit the request if the operation failed."}};
 }
 
 /**
@@ -1100,17 +1176,18 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json resourceExhaustion(const std::string& arg1) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.ResourceExhaustion"},
-      {"Message", "The resource " + arg1 +
-                      " was unable to satisfy the request "
-                      "due to unavailability of "
-                      "resources."},
-      {"Severity", "Critical"},
-      {"Resolution",
-       "Ensure that the resources are available and resubmit the request."}};
+nlohmann::json resourceExhaustion(const std::string& arg1)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.ResourceExhaustion"},
+        {"Message", "The resource " + arg1 +
+                        " was unable to satisfy the request "
+                        "due to unavailability of "
+                        "resources."},
+        {"Severity", "Critical"},
+        {"Resolution",
+         "Ensure that the resources are available and resubmit the request."}};
 }
 
 /**
@@ -1120,13 +1197,14 @@
  * See header file for more information
  * @endinternal
  */
-nlohmann::json accountModified() {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.AccountModified"},
-      {"Message", "The account was successfully modified."},
-      {"Severity", "OK"},
-      {"Resolution", "No resolution is required."}};
+nlohmann::json accountModified()
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.AccountModified"},
+        {"Message", "The account was successfully modified."},
+        {"Severity", "OK"},
+        {"Resolution", "No resolution is required."}};
 }
 
 /**
@@ -1138,24 +1216,26 @@
  */
 nlohmann::json queryParameterOutOfRange(const std::string& arg1,
                                         const std::string& arg2,
-                                        const std::string& arg3) {
-  return nlohmann::json{
-      {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
-      {"MessageId", "Base.1.2.0.QueryParameterOutOfRange"},
-      {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
-                      " is out of range " + arg3 + "."},
-      {"Severity", "Warning"},
-      {"Resolution",
-       "Reduce the value for the query parameter to a value that is within "
-       "range, such as a start or count value that is within bounds of the "
-       "number of resources in a collection or a page that is within the range "
-       "of valid pages."}};
+                                        const std::string& arg3)
+{
+    return nlohmann::json{
+        {"@odata.type", "/redfish/v1/$metadata#Message.v1_0_0.Message"},
+        {"MessageId", "Base.1.2.0.QueryParameterOutOfRange"},
+        {"Message", "The value " + arg1 + " for the query parameter " + arg2 +
+                        " is out of range " + arg3 + "."},
+        {"Severity", "Warning"},
+        {"Resolution",
+         "Reduce the value for the query parameter to a value that is within "
+         "range, such as a start or count value that is within bounds of the "
+         "number of resources in a collection or a page that is within the "
+         "range "
+         "of valid pages."}};
 }
 
 /*********************************
  * AUTOGENERATED FUNCTIONS END *
  *********************************/
 
-}  // namespace messages
+} // namespace messages
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/src/utils/json_utils.cpp b/redfish-core/src/utils/json_utils.cpp
index 5d81c21..868601f 100644
--- a/redfish-core/src/utils/json_utils.cpp
+++ b/redfish-core/src/utils/json_utils.cpp
@@ -14,440 +14,512 @@
 // limitations under the License.
 */
 #include "utils/json_utils.hpp"
+
 #include <error_messages.hpp>
 
-namespace redfish {
+namespace redfish
+{
 
-namespace json_util {
+namespace json_util
+{
 
 Result getString(const char* fieldName, const nlohmann::json& json,
-                 const std::string*& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 const std::string*& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  output = fieldIt->get_ptr<const std::string*>();
+    output = fieldIt->get_ptr<const std::string*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (output == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (output == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getObject(const char* fieldName, const nlohmann::json& json,
-                 nlohmann::json* output) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
+                 nlohmann::json* output)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
+    }
 
-  // Find field
-  auto fieldIt = json.find(fieldName);
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  // Verify type
-  if (!fieldIt->is_object()) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_object())
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  *output = *fieldIt;
+    // Extract value
+    *output = *fieldIt;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getArray(const char* fieldName, const nlohmann::json& json,
-                nlohmann::json* output) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
+                nlohmann::json* output)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
+    }
 
-  // Find field
-  auto fieldIt = json.find(fieldName);
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  // Verify type
-  if (!fieldIt->is_array()) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_array())
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  *output = *fieldIt;
+    // Extract value
+    *output = *fieldIt;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getInt(const char* fieldName, const nlohmann::json& json,
-              int64_t& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+              int64_t& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
+    const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
-                   uint64_t& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                   uint64_t& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
+    const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
-Result getBool(const char* fieldName, const nlohmann::json& json,
-               bool& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+Result getBool(const char* fieldName, const nlohmann::json& json, bool& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const bool* retVal = fieldIt->get_ptr<const bool*>();
+    const bool* retVal = fieldIt->get_ptr<const bool*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getDouble(const char* fieldName, const nlohmann::json& json,
-                 double& output) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 double& output)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    return Result::NOT_EXIST;
-  }
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        return Result::NOT_EXIST;
+    }
 
-  const double* retVal = fieldIt->get_ptr<const double*>();
+    const double* retVal = fieldIt->get_ptr<const double*>();
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    return Result::WRONG_TYPE;
-  }
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        return Result::WRONG_TYPE;
+    }
 
-  // Extract value
-  output = *retVal;
+    // Extract value
+    output = *retVal;
 
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getString(const char* fieldName, const nlohmann::json& json,
                  const std::string*& output, uint8_t msgCfgMap,
-                 nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    output = fieldIt->get_ptr<const std::string*>();
 
-  output = fieldIt->get_ptr<const std::string*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (output == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (output == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getObject(const char* fieldName, const nlohmann::json& json,
                  nlohmann::json* output, uint8_t msgCfgMap,
-                 nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
-
-  // Find field
-  auto fieldIt = json.find(fieldName);
-
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+                 nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
     }
 
-    return Result::NOT_EXIST;
-  }
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify type
-  if (!fieldIt->is_object()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_object())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Extract value
-  *output = *fieldIt;
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    // Extract value
+    *output = *fieldIt;
+
+    return Result::SUCCESS;
 }
 
 Result getArray(const char* fieldName, const nlohmann::json& json,
                 nlohmann::json* output, uint8_t msgCfgMap,
-                nlohmann::json& msgJson, const std::string&& fieldPath) {
-  // Verify input pointer
-  if (output == nullptr) {
-    return Result::NULL_POINTER;
-  }
-
-  // Find field
-  auto fieldIt = json.find(fieldName);
-
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+                nlohmann::json& msgJson, const std::string&& fieldPath)
+{
+    // Verify input pointer
+    if (output == nullptr)
+    {
+        return Result::NULL_POINTER;
     }
 
-    return Result::NOT_EXIST;
-  }
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify type
-  if (!fieldIt->is_array()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Verify type
+    if (!fieldIt->is_array())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Extract value
-  *output = *fieldIt;
+        return Result::WRONG_TYPE;
+    }
 
-  return Result::SUCCESS;
+    // Extract value
+    *output = *fieldIt;
+
+    return Result::SUCCESS;
 }
 
 Result getInt(const char* fieldName, const nlohmann::json& json,
               int64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-              const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+              const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
 
-  const int64_t* retVal = fieldIt->get_ptr<const int64_t*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getUnsigned(const char* fieldName, const nlohmann::json& json,
                    uint64_t& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-                   const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                   const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
 
-  const uint64_t* retVal = fieldIt->get_ptr<const uint64_t*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getBool(const char* fieldName, const nlohmann::json& json, bool& output,
                uint8_t msgCfgMap, nlohmann::json& msgJson,
-               const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+               const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const bool* retVal = fieldIt->get_ptr<const bool*>();
 
-  const bool* retVal = fieldIt->get_ptr<const bool*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 Result getDouble(const char* fieldName, const nlohmann::json& json,
                  double& output, uint8_t msgCfgMap, nlohmann::json& msgJson,
-                 const std::string&& fieldPath) {
-  // Find field
-  auto fieldIt = json.find(fieldName);
+                 const std::string&& fieldPath)
+{
+    // Find field
+    auto fieldIt = json.find(fieldName);
 
-  // Verify existence
-  if (fieldIt == json.end()) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::MISSING)) {
-      messages::addMessageToJson(msgJson, messages::propertyMissing(fieldName),
-                                 fieldPath);
+    // Verify existence
+    if (fieldIt == json.end())
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::MISSING))
+        {
+            messages::addMessageToJson(
+                msgJson, messages::propertyMissing(fieldName), fieldPath);
+        }
+
+        return Result::NOT_EXIST;
     }
 
-    return Result::NOT_EXIST;
-  }
+    const double* retVal = fieldIt->get_ptr<const double*>();
 
-  const double* retVal = fieldIt->get_ptr<const double*>();
+    // Verify type - we know that it exists, so nullptr means wrong type
+    if (retVal == nullptr)
+    {
+        if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR))
+        {
+            messages::addMessageToJson(
+                msgJson,
+                messages::propertyValueTypeError(fieldIt->dump(), fieldName),
+                fieldPath);
+        }
 
-  // Verify type - we know that it exists, so nullptr means wrong type
-  if (retVal == nullptr) {
-    if (msgCfgMap & static_cast<int>(MessageSetting::TYPE_ERROR)) {
-      messages::addMessageToJson(
-          msgJson, messages::propertyValueTypeError(fieldIt->dump(), fieldName),
-          fieldPath);
+        return Result::WRONG_TYPE;
     }
 
-    return Result::WRONG_TYPE;
-  }
+    // Extract value
+    output = *retVal;
 
-  // Extract value
-  output = *retVal;
-
-  return Result::SUCCESS;
+    return Result::SUCCESS;
 }
 
 bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
-                            nlohmann::json& reqJson) {
-  reqJson = nlohmann::json::parse(req.body, nullptr, false);
+                            nlohmann::json& reqJson)
+{
+    reqJson = nlohmann::json::parse(req.body, nullptr, false);
 
-  if (reqJson.is_discarded()) {
-    messages::addMessageToErrorJson(res.jsonValue, messages::malformedJSON());
+    if (reqJson.is_discarded())
+    {
+        messages::addMessageToErrorJson(res.jsonValue,
+                                        messages::malformedJSON());
 
-    res.result(boost::beast::http::status::bad_request);
-    res.end();
+        res.result(boost::beast::http::status::bad_request);
+        res.end();
 
-    return false;
-  }
+        return false;
+    }
 
-  return true;
+    return true;
 }
 
-}  // namespace json_util
+} // namespace json_util
 
-}  // namespace redfish
+} // namespace redfish
diff --git a/redfish-core/ut/privileges_test.cpp b/redfish-core/ut/privileges_test.cpp
index 92cd6c4..d857290 100644
--- a/redfish-core/ut/privileges_test.cpp
+++ b/redfish-core/ut/privileges_test.cpp
@@ -1,114 +1,127 @@
+#include "nlohmann/json.hpp"
 #include "privileges.hpp"
+
 #include <fstream>
 #include <string>
-#include "nlohmann/json.hpp"
+
 #include "gmock/gmock.h"
 
 using namespace redfish;
 
-TEST(PrivilegeTest, PrivilegeConstructor) {
-  Privileges privileges{"Login", "ConfigureManager"};
+TEST(PrivilegeTest, PrivilegeConstructor)
+{
+    Privileges privileges{"Login", "ConfigureManager"};
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::UnorderedElementsAre(
-                  ::testing::Pointee(&"Login"[0]),
-                  ::testing::Pointee(&"ConfigureManager"[0])));
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::UnorderedElementsAre(
+                    ::testing::Pointee(&"Login"[0]),
+                    ::testing::Pointee(&"ConfigureManager"[0])));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForNoPrivilegesRequired) {
-  Privileges userPrivileges{"Login"};
+TEST(PrivilegeTest, PrivilegeCheckForNoPrivilegesRequired)
+{
+    Privileges userPrivileges{"Login"};
 
-  OperationMap entityPrivileges{{boost::beast::http::verb::get, {{"Login"}}}};
+    OperationMap entityPrivileges{{boost::beast::http::verb::get, {{"Login"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess) {
-  auto userPrivileges = Privileges{"Login"};
-  OperationMap entityPrivileges{{boost::beast::http::verb::get, {}}};
+TEST(PrivilegeTest, PrivilegeCheckForSingleCaseSuccess)
+{
+    auto userPrivileges = Privileges{"Login"};
+    OperationMap entityPrivileges{{boost::beast::http::verb::get, {}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForSingleCaseFailure) {
-  auto userPrivileges = Privileges{"Login"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get, {{"ConfigureManager"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForSingleCaseFailure)
+{
+    auto userPrivileges = Privileges{"Login"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get, {{"ConfigureManager"}}}};
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForANDCaseSuccess) {
-  auto userPrivileges =
-      Privileges{"Login", "ConfigureManager", "ConfigureSelf"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get,
-       {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForANDCaseSuccess)
+{
+    auto userPrivileges =
+        Privileges{"Login", "ConfigureManager", "ConfigureSelf"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get,
+         {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForANDCaseFailure) {
-  auto userPrivileges = Privileges{"Login", "ConfigureManager"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get,
-       {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForANDCaseFailure)
+{
+    auto userPrivileges = Privileges{"Login", "ConfigureManager"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get,
+         {{"Login", "ConfigureManager", "ConfigureSelf"}}}};
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForORCaseSuccess) {
-  auto userPrivileges = Privileges{"ConfigureManager"};
-  OperationMap entityPrivileges{
-      {boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}};
+TEST(PrivilegeTest, PrivilegeCheckForORCaseSuccess)
+{
+    auto userPrivileges = Privileges{"ConfigureManager"};
+    OperationMap entityPrivileges{
+        {boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}};
 
-  EXPECT_TRUE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                            entityPrivileges, userPrivileges));
+    EXPECT_TRUE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, PrivilegeCheckForORCaseFailure) {
-  auto userPrivileges = Privileges{"ConfigureComponents"};
-  OperationMap entityPrivileges = OperationMap(
-      {{boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}});
+TEST(PrivilegeTest, PrivilegeCheckForORCaseFailure)
+{
+    auto userPrivileges = Privileges{"ConfigureComponents"};
+    OperationMap entityPrivileges = OperationMap(
+        {{boost::beast::http::verb::get, {{"Login"}, {"ConfigureManager"}}}});
 
-  EXPECT_FALSE(isMethodAllowedWithPrivileges(boost::beast::http::verb::get,
-                                             entityPrivileges, userPrivileges));
+    EXPECT_FALSE(isMethodAllowedWithPrivileges(
+        boost::beast::http::verb::get, entityPrivileges, userPrivileges));
 }
 
-TEST(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty) {
-  Privileges privileges;
+TEST(PrivilegeTest, DefaultPrivilegeBitsetsAreEmpty)
+{
+    Privileges privileges;
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::IsEmpty());
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::OEM),
+                ::testing::IsEmpty());
 }
 
-TEST(PrivilegeTest, GetActivePrivilegeNames) {
-  Privileges privileges;
+TEST(PrivilegeTest, GetActivePrivilegeNames)
+{
+    Privileges privileges;
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::IsEmpty());
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::IsEmpty());
 
-  std::array<const char*, 5> expectedPrivileges{
-      "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
-      "ConfigureSelf"};
+    std::array<const char*, 5> expectedPrivileges{
+        "Login", "ConfigureManager", "ConfigureUsers", "ConfigureComponents",
+        "ConfigureSelf"};
 
-  for (const auto& privilege : expectedPrivileges) {
-    EXPECT_TRUE(privileges.setSinglePrivilege(privilege));
-  }
+    for (const auto& privilege : expectedPrivileges)
+    {
+        EXPECT_TRUE(privileges.setSinglePrivilege(privilege));
+    }
 
-  EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
-              ::testing::UnorderedElementsAre(
-                  ::testing::Pointee(expectedPrivileges[0]),
-                  ::testing::Pointee(expectedPrivileges[1]),
-                  ::testing::Pointee(expectedPrivileges[2]),
-                  ::testing::Pointee(expectedPrivileges[3]),
-                  ::testing::Pointee(expectedPrivileges[4])));
+    EXPECT_THAT(privileges.getActivePrivilegeNames(PrivilegeType::BASE),
+                ::testing::UnorderedElementsAre(
+                    ::testing::Pointee(expectedPrivileges[0]),
+                    ::testing::Pointee(expectedPrivileges[1]),
+                    ::testing::Pointee(expectedPrivileges[2]),
+                    ::testing::Pointee(expectedPrivileges[3]),
+                    ::testing::Pointee(expectedPrivileges[4])));
 }
