Add Link support to Sessions

Similar to prior patchsets, add Link support to Session objects.

Tested: Redfish-protocol-validator passes.

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Icc74fc9d4ae2c6224528bc32b3696bf113d35d55
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 84657d4..37527dd 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -46,14 +46,27 @@
 }
 
 inline void
-    handleSessionGet(crow::App& app, const crow::Request& req,
-                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                     const std::string& sessionId)
+    handleSessionHead(crow::App& app, const crow::Request& req,
+                      const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                      const std::string& /*sessionId*/)
 {
+
     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
     {
         return;
     }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/Session/Session.json>; rel=describedby");
+}
+
+inline void
+    handleSessionGet(crow::App& app, const crow::Request& req,
+                     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+                     const std::string& sessionId)
+{
+    handleSessionHead(app, req, asyncResp, sessionId);
+
     // Note that control also reaches here via doPost and doDelete.
     auto session =
         persistent_data::SessionStore::getInstance().getSessionByUid(sessionId);
@@ -122,14 +135,25 @@
     return ret;
 }
 
-inline void handleSessionCollectionGet(
+inline void handleSessionCollectionHead(
     crow::App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 {
+
     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
     {
         return;
     }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/SessionCollection.json>; rel=describedby");
+}
+
+inline void handleSessionCollectionGet(
+    crow::App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    handleSessionCollectionHead(app, req, asyncResp);
     asyncResp->res.jsonValue["Members"] = getSessionCollectionMembers();
     asyncResp->res.jsonValue["Members@odata.count"] =
         asyncResp->res.jsonValue["Members"].size();
@@ -235,15 +259,25 @@
 
     fillSessionObject(asyncResp->res, *session);
 }
+inline void handleSessionServiceHead(
+    crow::App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.addHeader(
+        boost::beast::http::field::link,
+        "</redfish/v1/JsonSchemas/SessionService/SessionService.json>; rel=describedby");
+}
 inline void
     handleSessionServiceGet(crow::App& app, const crow::Request& req,
                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
 
 {
-    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-    {
-        return;
-    }
+    handleSessionServiceHead(app, req, asyncResp);
     asyncResp->res.jsonValue["@odata.type"] =
         "#SessionService.v1_0_2.SessionService";
     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/SessionService/";
@@ -300,6 +334,11 @@
 inline void requestRoutesSession(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
+        .privileges(redfish::privileges::headSession)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleSessionHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/<str>/")
         .privileges(redfish::privileges::getSession)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleSessionGet, std::ref(app)));
@@ -310,6 +349,11 @@
             std::bind_front(handleSessionDelete, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
+        .privileges(redfish::privileges::headSessionCollection)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleSessionCollectionHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/SessionService/Sessions/")
         .privileges(redfish::privileges::getSessionCollection)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleSessionCollectionGet, std::ref(app)));
@@ -330,6 +374,11 @@
             std::bind_front(handleSessionCollectionPost, std::ref(app)));
 
     BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
+        .privileges(redfish::privileges::headSessionService)
+        .methods(boost::beast::http::verb::head)(
+            std::bind_front(handleSessionServiceHead, std::ref(app)));
+
+    BMCWEB_ROUTE(app, "/redfish/v1/SessionService/")
         .privileges(redfish::privileges::getSessionService)
         .methods(boost::beast::http::verb::get)(
             std::bind_front(handleSessionServiceGet, std::ref(app)));