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
