blob: 8d3d7ae2b46bee7047d89a9d66a239101e673f58 [file] [log] [blame]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_APP_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_APP_H_
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "boost/asio/post.hpp" // NOLINT
#include "boost/asio/thread_pool.hpp" // NOLINT
#include "http_request.hpp"
#include "async_resp.hpp"
#include "tlbmc/service/hft_service.h"
#include "tlbmc/pacemaker/pacemaker.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/redfish/routing.h"
#include "resource.pb.h"
#include "tlbmc/store/store.h"
#include "app_interface.h"
#include "router_interface.h"
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define TLBMC_ROUTE(app, url) \
app.template AddRoute<crow::black_magic::GetParameterTag(url)>(url)
namespace milotic_tlbmc {
// RedfishApp is a class that can be used to register Redfish routes and
// callbacks.
//
// Example:
// RedfishApp app;
// TLBMC_ROUTE(app, "/foo/")
// .methods(boost::beast::http::verb::get)(
// [](const RedfishRequest& req, RedfishResponse& resp) {
// // business logic here
// });
// app.Validate();
//
// // Handle new coming request
// app.Handle(req, resp);
//
//
class RedfishApp : public ::crow::AppInterface {
public:
// The Redfish app for tlbmc only.
explicit RedfishApp(std::unique_ptr<Store> store);
explicit RedfishApp(std::unique_ptr<Pacemaker> pacemaker);
RedfishApp() = default;
RedfishApp(const RedfishApp&) = delete;
RedfishApp(RedfishApp&&) = delete;
RedfishApp& operator=(const RedfishApp&) = delete;
RedfishApp& operator=(const RedfishApp&&) = delete;
virtual ~RedfishApp() { thread_pool_.join(); }
// Takes ownership of the request and response and handles the request
// asynchronously.
void Handle(RedfishRequest&& req, RedfishResponse&& resp) const;
// Takes ownership of the request and response and handles the request
// synchronously.
void HandleFromCrowRequest(
const ::crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& async_resp) const override;
// Validates the routes and prepares the router for handling requests.
// Must be called before `Handle`.
void Validate();
// Returns the list of registered routes and their compressed method fields.
absl::flat_hash_map<std::string, size_t> GetRegisteredRoutes() const;
template <uint64_t Tag>
auto& AddRoute(std::string_view rule) {
return router_.NewRuleTagged<Tag>(rule);
}
template <uint64_t Tag, typename Func>
void ReplaceHandler(std::string_view url, boost::beast::http::verb verb,
Func&& func) {
router_.ReplaceHandler<Tag>(url, verb, func);
}
template <uint64_t Tag>
void RemoveHandler(std::string_view url, boost::beast::http::verb verb) {
router_.RemoveRuleTagged<Tag>(url, verb);
}
template <uint64_t Tag, typename Func>
void AppendHandler(std::string_view url, boost::beast::http::verb verb,
Func&& func) {
router_.AppendHandler<Tag>(url, verb, func);
}
// Returns the list of URLs and their methods that tlBMC fully owns.
// For an URL as a key, the value represents the method that is owned.
// These are URLs that tlBMC fully owns and can in-place replace gBMCWeb.
absl::flat_hash_map<std::string, size_t> GetOwnedUrls() const override;
absl::flat_hash_set<std::string> GetOwnedSubtrees() const override;
virtual Store* GetStore() const { return store_.get(); }
virtual crow::Router& GetRouter() { return router_; }
void SetSmartRouter(::crow::RouterInterface* smart_router) override;
void SetHftService(const milotic_hft::HftServiceImpl* hft_service) {
hft_service_ = hft_service;
}
const milotic_hft::HftServiceImpl* GetHftService() const {
return hft_service_;
}
void DebugPrint() const override;
protected:
void HandleInternal(const RedfishRequest& req, RedfishResponse& resp) const;
crow::Router router_;
std::unique_ptr<milotic_tlbmc::Store> store_;
mutable boost::asio::thread_pool thread_pool_;
std::unique_ptr<milotic_tlbmc::Pacemaker> pacemaker_;
const milotic_hft::HftServiceImpl* hft_service_ = nullptr;
};
absl::StatusOr<ResourceType> GetResourceType(
const std::unique_ptr<Store>& store, absl::string_view config_name);
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_APP_H_