Add Link header handling to PowerSubsystem

This commit is to update PowerSubsystem to respond to HEAD requests
in the way the redfish spec requires.

Tested:
HEAD /redfish/v1/Chassis/<str>/PowerSubsystem returns a correct
looking Link header.
Following that Link header resolves the schema file.

Get /redfish/v1/Chassis/BadChassis/PowerSubsystem returns 404.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I2f2a0e80b74471ddc037e899cfaf3ba307741475
diff --git a/redfish-core/lib/power_subsystem.hpp b/redfish-core/lib/power_subsystem.hpp
index 90559ef..17ee1af 100644
--- a/redfish-core/lib/power_subsystem.hpp
+++ b/redfish-core/lib/power_subsystem.hpp
@@ -20,11 +20,13 @@
 {
     if (!validChassisPath)
     {
-        BMCWEB_LOG_ERROR << "Not a valid chassis ID" << chassisId;
         messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
         return;
     }
 
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/PowerSubsystem/PowerSubsystem.json>; rel=describedby");
     asyncResp->res.jsonValue["@odata.type"] =
         "#PowerSubsystem.v1_1_0.PowerSubsystem";
     asyncResp->res.jsonValue["Name"] = "Power Subsystem";
@@ -33,10 +35,31 @@
         "redfish", "v1", "Chassis", chassisId, "PowerSubsystem");
     asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
     asyncResp->res.jsonValue["Status"]["Health"] = "OK";
+}
 
-    asyncResp->res.addHeader(
-        boost::beast::http::field::link,
-        "</redfish/v1/JsonSchemas/PowerSubsystem/PowerSubsystem.json>; rel=describedby");
+inline void handlePowerSubsystemCollectionHead(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& chassisId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    auto respHandler = [asyncResp, chassisId](
+                           const std::optional<std::string>& validChassisPath) {
+        if (!validChassisPath)
+        {
+            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+            return;
+        }
+        asyncResp->res.addHeader(
+            boost::beast::http::field::link,
+            "</redfish/v1/JsonSchemas/PowerSubsystem/PowerSubsystem.json>; rel=describedby");
+    };
+    redfish::chassis_utils::getValidChassisPath(asyncResp, chassisId,
+                                                std::move(respHandler));
 }
 
 inline void handlePowerSubsystemCollectionGet(
@@ -57,6 +80,11 @@
 inline void requestRoutesPowerSubsystem(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/")
+        .privileges(redfish::privileges::headPowerSubsystem)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handlePowerSubsystemCollectionHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/")
         .privileges(redfish::privileges::getPowerSubsystem)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handlePowerSubsystemCollectionGet, std::ref(app)));