diff --git a/meson.build b/meson.build
index 54cd92a..7be259b 100644
--- a/meson.build
+++ b/meson.build
@@ -393,6 +393,7 @@
   'include/ut/openbmc_dbus_rest_test.cpp',
   'redfish-core/include/utils/query_param_test.cpp',
   'redfish-core/lib/ut/service_root_test.cpp',
+  'redfish-core/lib/chassis_test.cpp',
   'redfish-core/ut/configfile_test.cpp',
   'redfish-core/ut/hex_utils_test.cpp',
   'redfish-core/ut/ip_utils_test.cpp',
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index cfa1832..7982281 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -17,6 +17,7 @@
 
 #include "health.hpp"
 #include "led.hpp"
+#include "utils/json_utils.hpp"
 
 #include <app.hpp>
 #include <dbus_utility.hpp>
@@ -131,6 +132,25 @@
         std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
 }
 
+inline void handleChassisCollectionGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#ChassisCollection.ChassisCollection";
+    asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
+    asyncResp->res.jsonValue["Name"] = "Chassis Collection";
+
+    collection_util::getCollectionMembers(
+        asyncResp, "/redfish/v1/Chassis",
+        {"xyz.openbmc_project.Inventory.Item.Board",
+         "xyz.openbmc_project.Inventory.Item.Chassis"});
+}
+
 /**
  * ChassisCollection derived class for delivering Chassis Collection Schema
  *  Functions triggers appropriate requests on DBus
@@ -140,22 +160,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
         .privileges(redfish::privileges::getChassisCollection)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ChassisCollection.ChassisCollection";
-        asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
-        asyncResp->res.jsonValue["Name"] = "Chassis Collection";
-
-        collection_util::getCollectionMembers(
-            asyncResp, "/redfish/v1/Chassis",
-            {"xyz.openbmc_project.Inventory.Item.Board",
-             "xyz.openbmc_project.Inventory.Item.Chassis"});
-        });
+            std::bind_front(handleChassisCollectionGet, std::ref(app)));
 }
 
 inline void
@@ -199,6 +204,363 @@
         });
 }
 
+inline void
+    handleChassisGet(App& app, const crow::Request& req,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                     const std::string& chassisId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    const std::array<const char*, 2> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Board",
+        "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, chassisId(std::string(chassisId))](
+            const boost::system::error_code ec,
+            const dbus::utility::MapperGetSubTreeResponse& subtree) {
+        if (ec)
+        {
+            messages::internalError(asyncResp->res);
+            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;
+
+            sdbusplus::message::object_path objPath(path);
+            if (objPath.filename() != chassisId)
+            {
+                continue;
+            }
+
+            auto health = std::make_shared<HealthPopulate>(asyncResp);
+
+            sdbusplus::asio::getProperty<std::vector<std::string>>(
+                *crow::connections::systemBus,
+                "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
+                "xyz.openbmc_project.Association", "endpoints",
+                [health](const boost::system::error_code ec2,
+                         const std::vector<std::string>& resp) {
+                if (ec2)
+                {
+                    return; // no sensors = no failures
+                }
+                health->inventory = resp;
+                });
+
+            health->populate();
+
+            if (connectionNames.empty())
+            {
+                BMCWEB_LOG_ERROR << "Got 0 Connection names";
+                continue;
+            }
+
+            asyncResp->res.jsonValue["@odata.type"] =
+                "#Chassis.v1_16_0.Chassis";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Chassis/" + chassisId;
+            asyncResp->res.jsonValue["Name"] = "Chassis Collection";
+            asyncResp->res.jsonValue["ChassisType"] = "RackMount";
+            asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
+                "/redfish/v1/Chassis/" + chassisId + "/Actions/Chassis.Reset";
+            asyncResp->res
+                .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
+                "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
+            asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
+                "/redfish/v1/Systems/system/PCIeDevices";
+
+            sdbusplus::asio::getProperty<std::vector<std::string>>(
+                *crow::connections::systemBus,
+                "xyz.openbmc_project.ObjectMapper", path + "/drive",
+                "xyz.openbmc_project.Association", "endpoints",
+                [asyncResp, chassisId](const boost::system::error_code ec3,
+                                       const std::vector<std::string>& resp) {
+                if (ec3 || resp.empty())
+                {
+                    return; // no drives = no failures
+                }
+
+                nlohmann::json reference;
+                reference["odata.id"] = crow::utility::urlFromPieces(
+                    "redfish", "v1", "Chassis", chassisId, "Drives");
+                asyncResp->res.jsonValue["Drives"] = std::move(reference);
+                });
+
+            const std::string& connectionName = connectionNames[0].first;
+
+            const std::vector<std::string>& interfaces2 =
+                connectionNames[0].second;
+            const std::array<const char*, 2> hasIndicatorLed = {
+                "xyz.openbmc_project.Inventory.Item.Panel",
+                "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
+
+            const std::string assetTagInterface =
+                "xyz.openbmc_project.Inventory.Decorator.AssetTag";
+            if (std::find(interfaces2.begin(), interfaces2.end(),
+                          assetTagInterface) != interfaces2.end())
+            {
+                sdbusplus::asio::getProperty<std::string>(
+                    *crow::connections::systemBus, connectionName, path,
+                    assetTagInterface, "AssetTag",
+                    [asyncResp, chassisId(std::string(chassisId))](
+                        const boost::system::error_code ec2,
+                        const std::string& property) {
+                    if (ec2)
+                    {
+                        BMCWEB_LOG_DEBUG << "DBus response error for AssetTag";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+                    asyncResp->res.jsonValue["AssetTag"] = property;
+                    });
+            }
+
+            for (const char* interface : hasIndicatorLed)
+            {
+                if (std::find(interfaces2.begin(), interfaces2.end(),
+                              interface) != interfaces2.end())
+                {
+                    getIndicatorLedState(asyncResp);
+                    getLocationIndicatorActive(asyncResp);
+                    break;
+                }
+            }
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp, chassisId(std::string(chassisId))](
+                    const boost::system::error_code /*ec2*/,
+                    const dbus::utility::DBusPropertiesMap& propertiesList) {
+                for (const std::pair<std::string,
+                                     dbus::utility::DbusVariantType>& property :
+                     propertiesList)
+                {
+                    // Store DBus properties that are also
+                    // Redfish properties with same name and a
+                    // string value
+                    const std::string& propertyName = property.first;
+                    if ((propertyName == "PartNumber") ||
+                        (propertyName == "SerialNumber") ||
+                        (propertyName == "Manufacturer") ||
+                        (propertyName == "Model") ||
+                        (propertyName == "SparePartNumber"))
+                    {
+                        const std::string* value =
+                            std::get_if<std::string>(&property.second);
+                        if (value == nullptr)
+                        {
+                            BMCWEB_LOG_ERROR << "Null value returned for "
+                                             << propertyName;
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+                        // SparePartNumber is optional on D-Bus
+                        // so skip if it is empty
+                        if (propertyName == "SparePartNumber")
+                        {
+                            if (value->empty())
+                            {
+                                continue;
+                            }
+                        }
+                        asyncResp->res.jsonValue[propertyName] = *value;
+                    }
+                }
+                asyncResp->res.jsonValue["Name"] = chassisId;
+                asyncResp->res.jsonValue["Id"] = chassisId;
+#ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
+                asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
+                    "/redfish/v1/Chassis/" + chassisId + "/Thermal";
+                // Power object
+                asyncResp->res.jsonValue["Power"]["@odata.id"] =
+                    "/redfish/v1/Chassis/" + chassisId + "/Power";
+#endif
+                // SensorCollection
+                asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
+                    "/redfish/v1/Chassis/" + chassisId + "/Sensors";
+                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+                nlohmann::json::array_t computerSystems;
+                nlohmann::json::object_t system;
+                system["@odata.id"] = "/redfish/v1/Systems/system";
+                computerSystems.push_back(std::move(system));
+                asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
+                    std::move(computerSystems);
+
+                nlohmann::json::array_t managedBy;
+                nlohmann::json::object_t manager;
+                manager["@odata.id"] = "/redfish/v1/Managers/bmc";
+                managedBy.push_back(std::move(manager));
+                asyncResp->res.jsonValue["Links"]["ManagedBy"] =
+                    std::move(managedBy);
+                getChassisState(asyncResp);
+                },
+                connectionName, path, "org.freedesktop.DBus.Properties",
+                "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
+
+            for (const auto& interface : interfaces2)
+            {
+                if (interface == "xyz.openbmc_project.Common.UUID")
+                {
+                    getChassisUUID(asyncResp, connectionName, path);
+                }
+                else if (interface ==
+                         "xyz.openbmc_project.Inventory.Decorator.LocationCode")
+                {
+                    getChassisLocationCode(asyncResp, connectionName, path);
+                }
+            }
+
+            return;
+        }
+
+        // Couldn't find an object with that name.  return an error
+        messages::resourceNotFound(asyncResp->res, "#Chassis.v1_16_0.Chassis",
+                                   chassisId);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/inventory", 0, interfaces);
+
+    getPhysicalSecurityData(asyncResp);
+}
+
+inline void
+    handleChassisPatch(App& app, const crow::Request& req,
+                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                       const std::string& param)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    std::optional<bool> locationIndicatorActive;
+    std::optional<std::string> indicatorLed;
+
+    if (param.empty())
+    {
+        return;
+    }
+
+    if (!json_util::readJsonPatch(
+            req, asyncResp->res, "LocationIndicatorActive",
+            locationIndicatorActive, "IndicatorLED", indicatorLed))
+    {
+        return;
+    }
+
+    // TODO (Gunnar): Remove IndicatorLED after enough time has passed
+    if (!locationIndicatorActive && !indicatorLed)
+    {
+        return; // delete this when we support more patch properties
+    }
+    if (indicatorLed)
+    {
+        asyncResp->res.addHeader(
+            boost::beast::http::field::warning,
+            "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
+    }
+
+    const std::array<const char*, 2> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Board",
+        "xyz.openbmc_project.Inventory.Item.Chassis"};
+
+    const std::string& chassisId = param;
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, chassisId, locationIndicatorActive,
+         indicatorLed](const boost::system::error_code ec,
+                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
+        if (ec)
+        {
+            messages::internalError(asyncResp->res);
+            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;
+
+            sdbusplus::message::object_path objPath(path);
+            if (objPath.filename() != chassisId)
+            {
+                continue;
+            }
+
+            if (connectionNames.empty())
+            {
+                BMCWEB_LOG_ERROR << "Got 0 Connection names";
+                continue;
+            }
+
+            const std::vector<std::string>& interfaces3 =
+                connectionNames[0].second;
+
+            const std::array<const char*, 2> hasIndicatorLed = {
+                "xyz.openbmc_project.Inventory.Item.Panel",
+                "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
+            bool indicatorChassis = false;
+            for (const char* interface : hasIndicatorLed)
+            {
+                if (std::find(interfaces3.begin(), interfaces3.end(),
+                              interface) != interfaces3.end())
+                {
+                    indicatorChassis = true;
+                    break;
+                }
+            }
+            if (locationIndicatorActive)
+            {
+                if (indicatorChassis)
+                {
+                    setLocationIndicatorActive(asyncResp,
+                                               *locationIndicatorActive);
+                }
+                else
+                {
+                    messages::propertyUnknown(asyncResp->res,
+                                              "LocationIndicatorActive");
+                }
+            }
+            if (indicatorLed)
+            {
+                if (indicatorChassis)
+                {
+                    setIndicatorLedState(asyncResp, *indicatorLed);
+                }
+                else
+                {
+                    messages::propertyUnknown(asyncResp->res, "IndicatorLED");
+                }
+            }
+            return;
+        }
+
+        messages::resourceNotFound(asyncResp->res, "#Chassis.v1_14_0.Chassis",
+                                   chassisId);
+        },
+        "xyz.openbmc_project.ObjectMapper",
+        "/xyz/openbmc_project/object_mapper",
+        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+        "/xyz/openbmc_project/inventory", 0, interfaces);
+}
+
 /**
  * Chassis override class for delivering Chassis Schema
  * Functions triggers appropriate requests on DBus
@@ -208,370 +570,12 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
         .privileges(redfish::privileges::getChassis)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& chassisId) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        const std::array<const char*, 2> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Board",
-            "xyz.openbmc_project.Inventory.Item.Chassis"};
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, chassisId(std::string(chassisId))](
-                const boost::system::error_code ec,
-                const dbus::utility::MapperGetSubTreeResponse& subtree) {
-            if (ec)
-            {
-                messages::internalError(asyncResp->res);
-                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;
-
-                sdbusplus::message::object_path objPath(path);
-                if (objPath.filename() != chassisId)
-                {
-                    continue;
-                }
-
-                auto health = std::make_shared<HealthPopulate>(asyncResp);
-
-                sdbusplus::asio::getProperty<std::vector<std::string>>(
-                    *crow::connections::systemBus,
-                    "xyz.openbmc_project.ObjectMapper", path + "/all_sensors",
-                    "xyz.openbmc_project.Association", "endpoints",
-                    [health](const boost::system::error_code ec2,
-                             const std::vector<std::string>& resp) {
-                    if (ec2)
-                    {
-                        return; // no sensors = no failures
-                    }
-                    health->inventory = resp;
-                    });
-
-                health->populate();
-
-                if (connectionNames.empty())
-                {
-                    BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                    continue;
-                }
-
-                asyncResp->res.jsonValue["@odata.type"] =
-                    "#Chassis.v1_16_0.Chassis";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Chassis/" + chassisId;
-                asyncResp->res.jsonValue["Name"] = "Chassis Collection";
-                asyncResp->res.jsonValue["ChassisType"] = "RackMount";
-                asyncResp->res
-                    .jsonValue["Actions"]["#Chassis.Reset"]["target"] =
-                    "/redfish/v1/Chassis/" + chassisId +
-                    "/Actions/Chassis.Reset";
-                asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]
-                                        ["@Redfish.ActionInfo"] =
-                    "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
-                asyncResp->res.jsonValue["PCIeDevices"]["@odata.id"] =
-                    "/redfish/v1/Systems/system/PCIeDevices";
-
-                sdbusplus::asio::getProperty<std::vector<std::string>>(
-                    *crow::connections::systemBus,
-                    "xyz.openbmc_project.ObjectMapper", path + "/drive",
-                    "xyz.openbmc_project.Association", "endpoints",
-                    [asyncResp,
-                     chassisId](const boost::system::error_code ec3,
-                                const std::vector<std::string>& resp) {
-                    if (ec3 || resp.empty())
-                    {
-                        return; // no drives = no failures
-                    }
-
-                    nlohmann::json reference;
-                    reference["odata.id"] = crow::utility::urlFromPieces(
-                        "redfish", "v1", "Chassis", chassisId, "Drives");
-                    asyncResp->res.jsonValue["Drives"] = std::move(reference);
-                    });
-
-                const std::string& connectionName = connectionNames[0].first;
-
-                const std::vector<std::string>& interfaces2 =
-                    connectionNames[0].second;
-                const std::array<const char*, 2> hasIndicatorLed = {
-                    "xyz.openbmc_project.Inventory.Item.Panel",
-                    "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
-
-                const std::string assetTagInterface =
-                    "xyz.openbmc_project.Inventory.Decorator.AssetTag";
-                if (std::find(interfaces2.begin(), interfaces2.end(),
-                              assetTagInterface) != interfaces2.end())
-                {
-                    sdbusplus::asio::getProperty<std::string>(
-                        *crow::connections::systemBus, connectionName, path,
-                        assetTagInterface, "AssetTag",
-                        [asyncResp, chassisId(std::string(chassisId))](
-                            const boost::system::error_code ec2,
-                            const std::string& property) {
-                        if (ec2)
-                        {
-                            BMCWEB_LOG_DEBUG
-                                << "DBus response error for AssetTag";
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-                        asyncResp->res.jsonValue["AssetTag"] = property;
-                        });
-                }
-
-                for (const char* interface : hasIndicatorLed)
-                {
-                    if (std::find(interfaces2.begin(), interfaces2.end(),
-                                  interface) != interfaces2.end())
-                    {
-                        getIndicatorLedState(asyncResp);
-                        getLocationIndicatorActive(asyncResp);
-                        break;
-                    }
-                }
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, chassisId(std::string(chassisId))](
-                        const boost::system::error_code /*ec2*/,
-                        const dbus::utility::DBusPropertiesMap&
-                            propertiesList) {
-                    for (const std::pair<std::string,
-                                         dbus::utility::DbusVariantType>&
-                             property : propertiesList)
-                    {
-                        // Store DBus properties that are also
-                        // Redfish properties with same name and a
-                        // string value
-                        const std::string& propertyName = property.first;
-                        if ((propertyName == "PartNumber") ||
-                            (propertyName == "SerialNumber") ||
-                            (propertyName == "Manufacturer") ||
-                            (propertyName == "Model") ||
-                            (propertyName == "SparePartNumber"))
-                        {
-                            const std::string* value =
-                                std::get_if<std::string>(&property.second);
-                            if (value == nullptr)
-                            {
-                                BMCWEB_LOG_ERROR << "Null value returned for "
-                                                 << propertyName;
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            // SparePartNumber is optional on D-Bus
-                            // so skip if it is empty
-                            if (propertyName == "SparePartNumber")
-                            {
-                                if (value->empty())
-                                {
-                                    continue;
-                                }
-                            }
-                            asyncResp->res.jsonValue[propertyName] = *value;
-                        }
-                    }
-                    asyncResp->res.jsonValue["Name"] = chassisId;
-                    asyncResp->res.jsonValue["Id"] = chassisId;
-#ifdef BMCWEB_ALLOW_DEPRECATED_POWER_THERMAL
-                    asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
-                        "/redfish/v1/Chassis/" + chassisId + "/Thermal";
-                    // Power object
-                    asyncResp->res.jsonValue["Power"]["@odata.id"] =
-                        "/redfish/v1/Chassis/" + chassisId + "/Power";
-#endif
-                    // SensorCollection
-                    asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
-                        "/redfish/v1/Chassis/" + chassisId + "/Sensors";
-                    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
-                    nlohmann::json::array_t computerSystems;
-                    nlohmann::json::object_t system;
-                    system["@odata.id"] = "/redfish/v1/Systems/system";
-                    computerSystems.push_back(std::move(system));
-                    asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
-                        std::move(computerSystems);
-
-                    nlohmann::json::array_t managedBy;
-                    nlohmann::json::object_t manager;
-                    manager["@odata.id"] = "/redfish/v1/Managers/bmc";
-                    managedBy.push_back(std::move(manager));
-                    asyncResp->res.jsonValue["Links"]["ManagedBy"] =
-                        std::move(managedBy);
-                    getChassisState(asyncResp);
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
-
-                for (const auto& interface : interfaces2)
-                {
-                    if (interface == "xyz.openbmc_project.Common.UUID")
-                    {
-                        getChassisUUID(asyncResp, connectionName, path);
-                    }
-                    else if (
-                        interface ==
-                        "xyz.openbmc_project.Inventory.Decorator.LocationCode")
-                    {
-                        getChassisLocationCode(asyncResp, connectionName, path);
-                    }
-                }
-
-                return;
-            }
-
-            // Couldn't find an object with that name.  return an error
-            messages::resourceNotFound(asyncResp->res,
-                                       "#Chassis.v1_16_0.Chassis", chassisId);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", 0, interfaces);
-
-        getPhysicalSecurityData(asyncResp);
-        });
+            std::bind_front(handleChassisGet, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
         .privileges(redfish::privileges::patchChassis)
         .methods(boost::beast::http::verb::patch)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& param) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        std::optional<bool> locationIndicatorActive;
-        std::optional<std::string> indicatorLed;
-
-        if (param.empty())
-        {
-            return;
-        }
-
-        if (!json_util::readJsonPatch(
-                req, asyncResp->res, "LocationIndicatorActive",
-                locationIndicatorActive, "IndicatorLED", indicatorLed))
-        {
-            return;
-        }
-
-        // TODO (Gunnar): Remove IndicatorLED after enough time has passed
-        if (!locationIndicatorActive && !indicatorLed)
-        {
-            return; // delete this when we support more patch properties
-        }
-        if (indicatorLed)
-        {
-            asyncResp->res.addHeader(
-                boost::beast::http::field::warning,
-                "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
-        }
-
-        const std::array<const char*, 2> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Board",
-            "xyz.openbmc_project.Inventory.Item.Chassis"};
-
-        const std::string& chassisId = param;
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, chassisId, locationIndicatorActive, indicatorLed](
-                const boost::system::error_code ec,
-                const dbus::utility::MapperGetSubTreeResponse& subtree) {
-            if (ec)
-            {
-                messages::internalError(asyncResp->res);
-                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;
-
-                sdbusplus::message::object_path objPath(path);
-                if (objPath.filename() != chassisId)
-                {
-                    continue;
-                }
-
-                if (connectionNames.empty())
-                {
-                    BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                    continue;
-                }
-
-                const std::vector<std::string>& interfaces3 =
-                    connectionNames[0].second;
-
-                const std::array<const char*, 2> hasIndicatorLed = {
-                    "xyz.openbmc_project.Inventory.Item.Panel",
-                    "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
-                bool indicatorChassis = false;
-                for (const char* interface : hasIndicatorLed)
-                {
-                    if (std::find(interfaces3.begin(), interfaces3.end(),
-                                  interface) != interfaces3.end())
-                    {
-                        indicatorChassis = true;
-                        break;
-                    }
-                }
-                if (locationIndicatorActive)
-                {
-                    if (indicatorChassis)
-                    {
-                        setLocationIndicatorActive(asyncResp,
-                                                   *locationIndicatorActive);
-                    }
-                    else
-                    {
-                        messages::propertyUnknown(asyncResp->res,
-                                                  "LocationIndicatorActive");
-                    }
-                }
-                if (indicatorLed)
-                {
-                    if (indicatorChassis)
-                    {
-                        setIndicatorLedState(asyncResp, *indicatorLed);
-                    }
-                    else
-                    {
-                        messages::propertyUnknown(asyncResp->res,
-                                                  "IndicatorLED");
-                    }
-                }
-                return;
-            }
-
-            messages::resourceNotFound(asyncResp->res,
-                                       "#Chassis.v1_14_0.Chassis", chassisId);
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", 0, interfaces);
-        });
+            std::bind_front(handleChassisPatch, std::ref(app)));
 }
 
 inline void
@@ -633,6 +637,36 @@
         busName, path, interface, method, "/", 0, interfaces);
 }
 
+inline void handleChassisResetActionInfoPost(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& /*chassisId*/)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
+
+    std::string resetType;
+
+    if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
+    {
+        return;
+    }
+
+    if (resetType != "PowerCycle")
+    {
+        BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
+                         << resetType;
+        messages::actionParameterNotSupported(asyncResp->res, resetType,
+                                              "ResetType");
+
+        return;
+    }
+    doChassisPowerCycle(asyncResp);
+}
+
 /**
  * ChassisResetAction class supports the POST method for the Reset
  * action.
@@ -645,34 +679,35 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
         .privileges(redfish::privileges::postChassis)
         .methods(boost::beast::http::verb::post)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string&) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        BMCWEB_LOG_DEBUG << "Post Chassis Reset.";
+            std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
+}
 
-        std::string resetType;
+inline void handleChassisResetActionInfoGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& chassisId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
+    asyncResp->res.jsonValue["Name"] = "Reset Action Info";
 
-        if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
-                                       resetType))
-        {
-            return;
-        }
+    asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
+    nlohmann::json::array_t parameters;
+    nlohmann::json::object_t parameter;
+    parameter["Name"] = "ResetType";
+    parameter["Required"] = true;
+    parameter["DataType"] = "String";
+    nlohmann::json::array_t allowed;
+    allowed.push_back("PowerCycle");
+    parameter["AllowableValues"] = std::move(allowed);
+    parameters.push_back(std::move(parameter));
 
-        if (resetType != "PowerCycle")
-        {
-            BMCWEB_LOG_DEBUG << "Invalid property value for ResetType: "
-                             << resetType;
-            messages::actionParameterNotSupported(asyncResp->res, resetType,
-                                                  "ResetType");
-
-            return;
-        }
-        doChassisPowerCycle(asyncResp);
-        });
+    asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
 }
 
 /**
@@ -684,32 +719,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
         .privileges(redfish::privileges::getActionInfo)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& chassisId) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#ActionInfo.v1_1_2.ActionInfo";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo";
-        asyncResp->res.jsonValue["Name"] = "Reset Action Info";
-
-        asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
-        nlohmann::json::array_t parameters;
-        nlohmann::json::object_t parameter;
-        parameter["Name"] = "ResetType";
-        parameter["Required"] = true;
-        parameter["DataType"] = "String";
-        nlohmann::json::array_t allowed;
-        allowed.push_back("PowerCycle");
-        parameter["AllowableValues"] = std::move(allowed);
-        parameters.push_back(std::move(parameter));
-
-        asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
-        });
+            std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
 }
 
 } // namespace redfish
diff --git a/redfish-core/lib/chassis_test.cpp b/redfish-core/lib/chassis_test.cpp
new file mode 100644
index 0000000..a043859
--- /dev/null
+++ b/redfish-core/lib/chassis_test.cpp
@@ -0,0 +1,60 @@
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "chassis.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+
+#include <boost/beast/core/string_type.hpp>
+#include <boost/beast/http/message.hpp>
+#include <nlohmann/json.hpp>
+
+#include <system_error>
+
+#include <gtest/gtest.h>
+
+namespace redfish
+{
+namespace
+{
+
+void assertChassisResetActionInfoGet(const std::string& chassisId,
+                                     crow::Response& res)
+{
+    EXPECT_EQ(res.jsonValue["@odata.type"], "#ActionInfo.v1_1_2.ActionInfo");
+    EXPECT_EQ(res.jsonValue["@odata.id"],
+              "/redfish/v1/Chassis/" + chassisId + "/ResetActionInfo");
+    EXPECT_EQ(res.jsonValue["Name"], "Reset Action Info");
+
+    EXPECT_EQ(res.jsonValue["Id"], "ResetActionInfo");
+
+    nlohmann::json::array_t parameters;
+    nlohmann::json::object_t parameter;
+    parameter["Name"] = "ResetType";
+    parameter["Required"] = true;
+    parameter["DataType"] = "String";
+    nlohmann::json::array_t allowed;
+    allowed.push_back("PowerCycle");
+    parameter["AllowableValues"] = std::move(allowed);
+    parameters.push_back(std::move(parameter));
+
+    EXPECT_EQ(res.jsonValue["Parameters"], parameters);
+}
+
+TEST(HandleChassisResetActionInfoGet, StaticAttributesAreExpected)
+{
+
+    auto response = std::make_shared<bmcweb::AsyncResp>();
+    std::error_code err;
+    crow::Request request{{boost::beast::http::verb::get, "/whatever", 11},
+                          err};
+
+    std::string fakeChassis = "fakeChassis";
+    response->res.setCompleteRequestHandler(
+        std::bind_front(assertChassisResetActionInfoGet, fakeChassis));
+
+    crow::App app;
+    handleChassisResetActionInfoGet(app, request, response, fakeChassis);
+}
+
+} // namespace
+} // namespace redfish
\ No newline at end of file
diff --git a/redfish-core/lib/redfish_util.hpp b/redfish-core/lib/redfish_util.hpp
index e050594..04d6ceb 100644
--- a/redfish-core/lib/redfish_util.hpp
+++ b/redfish-core/lib/redfish_util.hpp
@@ -17,6 +17,10 @@
 #ifndef BMCWEB_ENABLE_REDFISH_ONE_CHASSIS
 
 #include <dbus_utility.hpp>
+#include <sdbusplus/asio/property.hpp>
+
+#include <charconv>
+
 namespace redfish
 {
 
