From ffe6d597d9e3d4407cf8062b5d6505a80ce08f41 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Tue, 28 Sep 2021 12:04:51 -0700 Subject: Update to internal 0.75 Signed-off-by: Jason M. Bills --- ...-Add-PhysicalContext-to-Thermal-resources.patch | 31 +- ...-Support-new-boot-override-setting-design.patch | 723 --------------------- .../0003-Add-support-to-ResetBios-action.patch | 26 +- .../0004-Add-Server-Sent-Events-support.patch | 19 +- ...tyle-subscription-support-to-eventservice.patch | 41 +- .../0006-Add-EventService-SSE-filter-support.patch | 10 +- ...rvice-Log-events-for-subscription-actions.patch | 42 +- ...cture-Redifsh-EventLog-Transmit-code-flow.patch | 20 +- ...1-Add-support-for-MetricDefinition-scheme.patch | 420 ++++++------ ...2-Sync-Telmetry-service-with-EventService.patch | 20 +- ...t-Remove-LogService-from-TelemetryService.patch | 26 - ...d-bmcweb-to-use-new-telemetry-service-API.patch | 301 +++++++++ ...MetricDefinition-property-in-MetricReport.patch | 267 ++++++++ ...rvice-fix-added-Context-field-to-response.patch | 29 - .../0005-Add-DELETE-method-for-MetricReport.patch | 132 ++++ ...d-bmcweb-to-use-new-telemetry-service-API.patch | 301 --------- ...0006-Add-GET-method-for-TriggerCollection.patch | 313 +++++++++ ...MetricDefinition-property-in-MetricReport.patch | 268 -------- ...eneralize-ReadingType-in-MetricDefinition.patch | 168 ----- ...t-Remove-LogService-from-TelemetryService.patch | 26 + ...rvice-fix-added-Context-field-to-response.patch | 29 + ...eneralize-ReadingType-in-MetricDefinition.patch | 93 +++ .../interfaces/bmcweb/telemetry/README | 28 +- ...status-code-from-InsertMedia-REST-methods.patch | 25 +- .../recipes-phosphor/interfaces/bmcweb_%.bbappend | 27 +- 25 files changed, 1547 insertions(+), 1838 deletions(-) delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0025-Revert-Support-new-boot-override-setting-design.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Switched-bmcweb-to-use-new-telemetry-service-API.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces') diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0011-bmcweb-Add-PhysicalContext-to-Thermal-resources.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0011-bmcweb-Add-PhysicalContext-to-Thermal-resources.patch index e52dff3f4..f41e6f994 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0011-bmcweb-Add-PhysicalContext-to-Thermal-resources.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0011-bmcweb-Add-PhysicalContext-to-Thermal-resources.patch @@ -65,6 +65,24 @@ Response: }, "UpperThresholdCritical": 115.0, "UpperThresholdNonCritical": 110.0 +}, +{ + @odata.id": "/redfish/v1/Chassis/F2U8X25_HSBP_2/Thermal#/Temperatures/0", + @odata.type": "#Thermal.v1_3_0.Temperature", + LowerThresholdCritical": 7.0, + LowerThresholdNonCritical": 12.0, + MaxReadingRangeTemp": 127.0, + MemberId": "HSBP2_Temp", + MinReadingRangeTemp": -128.0, + Name": "HSBP2 Temp", + PhysicalContext": "Backplane", + ReadingCelsius": 21.437, + Status": { + "Health": "OK", + "State": "Enabled" + }, + UpperThresholdCritical": 57.0, + UpperThresholdNonCritical": 52.0 } 3. GET - https:///redfish/v1/Chassis//Power Response: @@ -103,15 +121,16 @@ Response: } } Signed-off-by: Snehalatha Venkatesh +Signed-off-by: sunitakx --- - redfish-core/lib/sensors.hpp | 12 ++++++++++++ - 1 file changed, 12 insertions(+) + redfish-core/lib/sensors.hpp | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp -index 9f06d2f..40fcdf8 100644 +index 5d27577..d51d09f 100644 --- a/redfish-core/lib/sensors.hpp +++ b/redfish-core/lib/sensors.hpp -@@ -964,6 +964,18 @@ inline void objectInterfacesToJson( +@@ -973,6 +973,22 @@ inline void objectInterfacesToJson( { unit = "/ReadingCelsius"_json_pointer; sensorJson["@odata.type"] = "#Thermal.v1_3_0.Temperature"; @@ -123,6 +142,10 @@ index 9f06d2f..40fcdf8 100644 + { + sensorJson["PhysicalContext"] = "Intake"; + } ++ else if (sensorName.find("HSBP") != std::string::npos) ++ { ++ sensorJson["PhysicalContext"] = "Backplane"; ++ } + else + { + sensorJson["PhysicalContext"] = "SystemBoard"; diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0025-Revert-Support-new-boot-override-setting-design.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0025-Revert-Support-new-boot-override-setting-design.patch deleted file mode 100644 index e0664a350..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0025-Revert-Support-new-boot-override-setting-design.patch +++ /dev/null @@ -1,723 +0,0 @@ -From c6ed122a09b1e41b9eab0032ff428b8b1a999534 Mon Sep 17 00:00:00 2001 -From: Jae Hyun Yoo -Date: Wed, 4 Aug 2021 15:50:34 -0700 -Subject: [PATCH] Revert "Support new boot override setting design" - -This reverts commit c21865c469cfc9dffdc15d87710293115cf6d9e4. - -Change-Id: Icfd03551dd9ea2fb216519d8ab05b92521838542 -Signed-off-by: Jae Hyun Yoo ---- - redfish-core/lib/systems.hpp | 493 +++++++++++++++++------------------ - 1 file changed, 245 insertions(+), 248 deletions(-) - -diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp -index fc6e2c78fd1f..5ad065b3518a 100644 ---- a/redfish-core/lib/systems.hpp -+++ b/redfish-core/lib/systems.hpp -@@ -769,8 +769,11 @@ inline int assignBootParameters(const std::shared_ptr& aResp, - const std::string& rfSource, - std::string& bootSource, std::string& bootMode) - { -- bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; -- bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; -+ // The caller has initialized the bootSource and bootMode to: -+ // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; -+ // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; -+ // Only modify the bootSource/bootMode variable needed to achieve the -+ // desired boot action. - - if (rfSource == "None") - { -@@ -917,14 +920,45 @@ inline void getBootProgress(const std::shared_ptr& aResp) - } - - /** -- * @brief Retrieves boot override type over DBUS and fills out the response -+ * @brief Checks if the current boot override state can be considered as -+ * Disabled - * - * @param[in] aResp Shared pointer for generating response message. - * - * @return None. - */ -+inline void -+ checkIfOverrideIsDisabled(const std::shared_ptr& aResp) -+{ -+ // If the BootSourceOverrideTarget is still "None" at the end, -+ // reset the BootSourceOverrideEnabled to indicate that -+ // overrides are disabled -+ if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] == "None") -+ { -+ // If the BootSourceOverrideMode is supported we should -+ // check if it is still "UEFI" too -+ if (aResp->res.jsonValue["Boot"].contains("BootSourceOverrideMode")) -+ { -+ if (aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] != -+ "UEFI") -+ { -+ return; -+ } -+ } -+ aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; -+ } -+} - --inline void getBootOverrideType(const std::shared_ptr& aResp) -+/** -+ * @brief Retrieves boot type over DBUS and fills out the response -+ * -+ * @param[in] aResp Shared pointer for generating response message. -+ * @param[in] bootDbusObj The dbus object to query for boot properties. -+ * -+ * @return None. -+ */ -+inline void getBootType(const std::shared_ptr& aResp, -+ const std::string& bootDbusObj) - { - crow::connections::systemBus->async_method_call( - [aResp](const boost::system::error_code ec, -@@ -932,6 +966,12 @@ inline void getBootOverrideType(const std::shared_ptr& aResp) - if (ec) - { - // not an error, don't have to have the interface -+ -+ // Support Disabled override state in a way: -+ // "BootSourceOverrideEnabled=Disabled" = -+ // "BootSourceOverrideMode=UEFI" + -+ // "BootSourceOverrideTarget=None" -+ checkIfOverrideIsDisabled(aResp); - return; - } - -@@ -958,26 +998,31 @@ inline void getBootOverrideType(const std::shared_ptr& aResp) - } - - aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType; -+ -+ // Support Disabled override state in a way: -+ // "BootSourceOverrideEnabled=Disabled" = -+ // "BootSourceOverrideMode=UEFI" + "BootSourceOverrideTarget=None" -+ checkIfOverrideIsDisabled(aResp); - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "xyz.openbmc_project.Settings", bootDbusObj, - "org.freedesktop.DBus.Properties", "Get", - "xyz.openbmc_project.Control.Boot.Type", "BootType"); - } - - /** -- * @brief Retrieves boot override mode over DBUS and fills out the response -+ * @brief Retrieves boot mode over DBUS and fills out the response - * - * @param[in] aResp Shared pointer for generating response message. -+ * @param[in] bootDbusObj The dbus object to query for boot properties. - * - * @return None. - */ -- --inline void getBootOverrideMode(const std::shared_ptr& aResp) -+inline void getBootMode(const std::shared_ptr& aResp, -+ const std::string& bootDbusObj) - { - crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec, -- const std::variant& bootMode) { -+ [aResp, bootDbusObj](const boost::system::error_code ec, -+ const std::variant& bootMode) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -@@ -1010,27 +1055,39 @@ inline void getBootOverrideMode(const std::shared_ptr& aResp) - rfMode; - } - } -+ -+ // Get BootType inside this async call as we need all of the -+ // BootSource/BootMode/BootType to support -+ // "BootSourceOverrideEnabled"="Disabled" state. -+ getBootType(aResp, bootDbusObj); - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "xyz.openbmc_project.Settings", bootDbusObj, - "org.freedesktop.DBus.Properties", "Get", - "xyz.openbmc_project.Control.Boot.Mode", "BootMode"); - } - - /** -- * @brief Retrieves boot override source over DBUS -+ * @brief Retrieves boot source over DBUS - * - * @param[in] aResp Shared pointer for generating response message. -+ * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time. - * - * @return None. - */ -- --inline void -- getBootOverrideSource(const std::shared_ptr& aResp) -+inline void getBootSource(const std::shared_ptr& aResp, -+ bool oneTimeEnabled) - { -+ std::string bootDbusObj = -+ oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time" -+ : "/xyz/openbmc_project/control/host0/boot"; -+ -+ BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled; -+ aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = -+ (oneTimeEnabled) ? "Once" : "Continuous"; -+ - crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec, -- const std::variant& bootSource) { -+ [aResp, bootDbusObj](const boost::system::error_code ec, -+ const std::variant& bootSource) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -@@ -1057,43 +1114,32 @@ inline void - - // Get BootMode as BootSourceOverrideTarget is constructed - // from both BootSource and BootMode -- getBootOverrideMode(aResp); -+ getBootMode(aResp, bootDbusObj); - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "xyz.openbmc_project.Settings", bootDbusObj, - "org.freedesktop.DBus.Properties", "Get", - "xyz.openbmc_project.Control.Boot.Source", "BootSource"); - } - - /** -- * @brief This functions abstracts all the logic behind getting a -- * "BootSourceOverrideEnabled" property from an overall boot override enable -- * state -+ * @brief Retrieves "One time" enabled setting over DBUS and calls function to -+ * get boot source and boot mode. - * - * @param[in] aResp Shared pointer for generating response message. - * - * @return None. - */ -- --inline void -- processBootOverrideEnable(const std::shared_ptr& aResp, -- const bool bootOverrideEnableSetting) -+inline void getBootProperties(const std::shared_ptr& aResp) - { -- if (!bootOverrideEnableSetting) -- { -- aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled"; -- return; -- } -+ BMCWEB_LOG_DEBUG << "Get boot information."; - -- // If boot source override is enabled, we need to check 'one_time' -- // property to set a correct value for the "BootSourceOverrideEnabled" - crow::connections::systemBus->async_method_call( - [aResp](const boost::system::error_code ec, - const std::variant& oneTime) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -- messages::internalError(aResp->res); -+ // not an error, don't have to have the interface - return; - } - -@@ -1104,19 +1150,7 @@ inline void - messages::internalError(aResp->res); - return; - } -- -- bool oneTimeSetting = *oneTimePtr; -- -- if (oneTimeSetting) -- { -- aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = -- "Once"; -- } -- else -- { -- aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = -- "Continuous"; -- } -+ getBootSource(aResp, *oneTimePtr); - }, - "xyz.openbmc_project.Settings", - "/xyz/openbmc_project/control/host0/boot/one_time", -@@ -1124,60 +1158,6 @@ inline void - "xyz.openbmc_project.Object.Enable", "Enabled"); - } - --/** -- * @brief Retrieves boot override enable over DBUS -- * -- * @param[in] aResp Shared pointer for generating response message. -- * -- * @return None. -- */ -- --inline void -- getBootOverrideEnable(const std::shared_ptr& aResp) --{ -- crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec, -- const std::variant& bootOverrideEnable) { -- if (ec) -- { -- BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -- messages::internalError(aResp->res); -- return; -- } -- -- const bool* bootOverrideEnablePtr = -- std::get_if(&bootOverrideEnable); -- -- if (!bootOverrideEnablePtr) -- { -- messages::internalError(aResp->res); -- return; -- } -- -- processBootOverrideEnable(aResp, *bootOverrideEnablePtr); -- }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -- "org.freedesktop.DBus.Properties", "Get", -- "xyz.openbmc_project.Object.Enable", "Enabled"); --} -- --/** -- * @brief Retrieves boot source override properties -- * -- * @param[in] aResp Shared pointer for generating response message. -- * -- * @return None. -- */ --inline void getBootProperties(const std::shared_ptr& aResp) --{ -- BMCWEB_LOG_DEBUG << "Get boot information."; -- -- getBootOverrideSource(aResp); -- getBootOverrideType(aResp); -- getBootOverrideEnable(aResp); --} -- - /** - * @brief Retrieves the Last Reset Time - * -@@ -1479,47 +1459,59 @@ inline void getTrustedModuleRequiredToBoot( - * @brief Sets boot properties into DBUS object(s). - * - * @param[in] aResp Shared pointer for generating response message. -+ * @param[in] overrideEnabled The source override "enable". -+ * @param[in] bootObj Path to the DBUS object. - * @param[in] bootType The boot type to set. - * @return Integer error code. - */ - inline void setBootType(const std::shared_ptr& aResp, -+ const bool overrideEnabled, const std::string& bootObj, - const std::optional& bootType) - { -- std::string bootTypeStr; -- -- if (!bootType) -- { -- return; -- } -+ std::string bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; - -- // Source target specified -- BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; -- // Figure out which DBUS interface and property to use -- if (*bootType == "Legacy") -- { -- bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; -- } -- else if (*bootType == "UEFI") -+ if (bootType && overrideEnabled) - { -- bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; -- } -- else -- { -- BMCWEB_LOG_DEBUG << "Invalid property value for " -- "BootSourceOverrideMode: " -- << *bootType; -- messages::propertyValueNotInList(aResp->res, *bootType, -- "BootSourceOverrideMode"); -- return; -+ // Source target specified -+ BMCWEB_LOG_DEBUG << "Boot type: " << *bootType; -+ // Figure out which DBUS interface and property to use -+ if (*bootType == "Legacy") -+ { -+ bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy"; -+ } -+ else if (*bootType == "UEFI") -+ { -+ bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI"; -+ } -+ else -+ { -+ BMCWEB_LOG_DEBUG << "Invalid property value for " -+ "BootSourceOverrideMode: " -+ << *bootType; -+ messages::propertyValueNotInList(aResp->res, *bootType, -+ "BootSourceOverrideMode"); -+ return; -+ } - } - - // Act on validated parameters - BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr; - - crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec) { -+ [aResp, bootType](const boost::system::error_code ec) { - if (ec) - { -+ if (!bootType) -+ { -+ // If bootType wasn't explicitly present in the incoming -+ // message don't output error. The error could come from a -+ // fact that the BootType interface may be not present in -+ // the settings object. It could happen because this -+ // interface is not relevant for some Host architectures -+ // (for example POWER). -+ return; -+ } -+ - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; - if (ec.value() == boost::asio::error::host_unreachable) - { -@@ -1531,8 +1523,7 @@ inline void setBootType(const std::shared_ptr& aResp, - } - BMCWEB_LOG_DEBUG << "Boot type update done."; - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "xyz.openbmc_project.Settings", bootObj, - "org.freedesktop.DBus.Properties", "Set", - "xyz.openbmc_project.Control.Boot.Type", "BootType", - std::variant(bootTypeStr)); -@@ -1542,48 +1533,42 @@ inline void setBootType(const std::shared_ptr& aResp, - * @brief Sets boot properties into DBUS object(s). - * - * @param[in] aResp Shared pointer for generating response message. -- * @param[in] bootType The boot type to set. -+ * @param[in] overrideEnabled The source override "enable". -+ * @param[in] bootObj Path to the DBUS object. -+ * @param[in] bootSource The boot source to set. -+ * - * @return Integer error code. - */ --inline void setBootEnable(const std::shared_ptr& aResp, -- const std::optional& bootEnable) -+inline void setBootModeOrSource(const std::shared_ptr& aResp, -+ const bool overrideEnabled, -+ const std::string& bootObj, -+ const std::optional& bootSource) - { -- if (!bootEnable) -- { -- return; -- } -- // Source target specified -- BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable; -+ std::string bootSourceStr = -+ "xyz.openbmc_project.Control.Boot.Source.Sources.Default"; -+ std::string bootModeStr = -+ "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular"; - -- bool bootOverrideEnable = false; -- bool bootOverridePersistent = false; -- // Figure out which DBUS interface and property to use -- if (*bootEnable == "Disabled") -- { -- bootOverrideEnable = false; -- } -- else if (*bootEnable == "Once") -- { -- bootOverrideEnable = true; -- bootOverridePersistent = false; -- } -- else if (*bootEnable == "Continuous") -+ if (bootSource && overrideEnabled) - { -- bootOverrideEnable = true; -- bootOverridePersistent = true; -- } -- else -- { -- BMCWEB_LOG_DEBUG << "Invalid property value for " -- "BootSourceOverrideEnabled: " -- << *bootEnable; -- messages::propertyValueNotInList(aResp->res, *bootEnable, -- "BootSourceOverrideEnabled"); -- return; -+ // Source target specified -+ BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; -+ // Figure out which DBUS interface and property to use -+ if (assignBootParameters(aResp, *bootSource, bootSourceStr, -+ bootModeStr)) -+ { -+ BMCWEB_LOG_DEBUG -+ << "Invalid property value for BootSourceOverrideTarget: " -+ << *bootSource; -+ messages::propertyValueNotInList(aResp->res, *bootSource, -+ "BootSourceTargetOverride"); -+ return; -+ } - } - - // Act on validated parameters -- BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable; -+ BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; -+ BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; - - crow::connections::systemBus->async_method_call( - [aResp](const boost::system::error_code ec) { -@@ -1593,23 +1578,12 @@ inline void setBootEnable(const std::shared_ptr& aResp, - messages::internalError(aResp->res); - return; - } -- BMCWEB_LOG_DEBUG << "Boot override enable update done."; -+ BMCWEB_LOG_DEBUG << "Boot source update done."; - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "xyz.openbmc_project.Settings", bootObj, - "org.freedesktop.DBus.Properties", "Set", -- "xyz.openbmc_project.Object.Enable", "Enabled", -- std::variant(bootOverrideEnable)); -- -- if (!bootOverrideEnable) -- { -- return; -- } -- -- // In case boot override is enabled we need to set correct value for the -- // 'one_time' enable DBus interface -- BMCWEB_LOG_DEBUG << "DBUS boot override persistent: " -- << bootOverridePersistent; -+ "xyz.openbmc_project.Control.Boot.Source", "BootSource", -+ std::variant(bootSourceStr)); - - crow::connections::systemBus->async_method_call( - [aResp](const boost::system::error_code ec) { -@@ -1619,86 +1593,45 @@ inline void setBootEnable(const std::shared_ptr& aResp, - messages::internalError(aResp->res); - return; - } -- BMCWEB_LOG_DEBUG << "Boot one_time update done."; -+ BMCWEB_LOG_DEBUG << "Boot mode update done."; - }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot/one_time", -+ "xyz.openbmc_project.Settings", bootObj, - "org.freedesktop.DBus.Properties", "Set", -- "xyz.openbmc_project.Object.Enable", "Enabled", -- std::variant(!bootOverridePersistent)); -+ "xyz.openbmc_project.Control.Boot.Mode", "BootMode", -+ std::variant(bootModeStr)); - } - - /** -- * @brief Sets boot properties into DBUS object(s). -+ * @brief Sets "One time" enabled setting into DBUS object - * -- * @param[in] aResp Shared pointer for generating response message. -- * @param[in] bootSource The boot source to set. -+ * @param[in] aResp Shared pointer for generating response message. -+ * @param[in] oneTime Enable property for one-time object - * - * @return Integer error code. - */ --inline void setBootModeOrSource(const std::shared_ptr& aResp, -- const std::optional& bootSource) -+inline void setOneTime(const std::shared_ptr& aResp, -+ bool oneTime) - { -- std::string bootSourceStr; -- std::string bootModeStr; -- -- if (!bootSource) -- { -- return; -- } -- -- // Source target specified -- BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource; -- // Figure out which DBUS interface and property to use -- if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr)) -- { -- BMCWEB_LOG_DEBUG -- << "Invalid property value for BootSourceOverrideTarget: " -- << *bootSource; -- messages::propertyValueNotInList(aResp->res, *bootSource, -- "BootSourceTargetOverride"); -- return; -- } -- -- // Act on validated parameters -- BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr; -- BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr; -- - crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec) { -+ [aResp{aResp}](const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; - messages::internalError(aResp->res); - return; - } -- BMCWEB_LOG_DEBUG << "Boot source update done."; -+ BMCWEB_LOG_DEBUG << "Boot enable update done."; - }, - "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -- "org.freedesktop.DBus.Properties", "Set", -- "xyz.openbmc_project.Control.Boot.Source", "BootSource", -- std::variant(bootSourceStr)); -- -- crow::connections::systemBus->async_method_call( -- [aResp](const boost::system::error_code ec) { -- if (ec) -- { -- BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -- messages::internalError(aResp->res); -- return; -- } -- BMCWEB_LOG_DEBUG << "Boot mode update done."; -- }, -- "xyz.openbmc_project.Settings", -- "/xyz/openbmc_project/control/host0/boot", -+ "/xyz/openbmc_project/control/host0/boot/one_time", - "org.freedesktop.DBus.Properties", "Set", -- "xyz.openbmc_project.Control.Boot.Mode", "BootMode", -- std::variant(bootModeStr)); -+ "xyz.openbmc_project.Object.Enable", "Enabled", -+ std::variant(oneTime)); - } - - /** -- * @brief Sets Boot source override properties. -+ * @brief Retrieves "One time" enabled setting over DBUS and calls function to -+ * set boot source/boot mode properties. - * - * @param[in] aResp Shared pointer for generating response message. - * @param[in] bootSource The boot source from incoming RF request. -@@ -1707,17 +1640,81 @@ inline void setBootModeOrSource(const std::shared_ptr& aResp, - * - * @return Integer error code. - */ -- --inline void setBootProperties(const std::shared_ptr& aResp, -- const std::optional& bootSource, -- const std::optional& bootType, -- const std::optional& bootEnable) -+inline void -+ setBootSourceProperties(const std::shared_ptr& aResp, -+ std::optional bootSource, -+ std::optional bootType, -+ std::optional bootEnable) - { - BMCWEB_LOG_DEBUG << "Set boot information."; - -- setBootModeOrSource(aResp, bootSource); -- setBootType(aResp, bootType); -- setBootEnable(aResp, bootEnable); -+ crow::connections::systemBus->async_method_call( -+ [aResp, bootSource{std::move(bootSource)}, -+ bootType{std::move(bootType)}, -+ bootEnable{std::move(bootEnable)}](const boost::system::error_code ec, -+ const std::variant& oneTime) { -+ if (ec) -+ { -+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec; -+ messages::internalError(aResp->res); -+ return; -+ } -+ -+ const bool* oneTimePtr = std::get_if(&oneTime); -+ -+ if (!oneTimePtr) -+ { -+ messages::internalError(aResp->res); -+ return; -+ } -+ -+ BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr; -+ -+ bool oneTimeSetting = *oneTimePtr; -+ bool overrideEnabled = true; -+ -+ // Validate incoming parameters -+ if (bootEnable) -+ { -+ if (*bootEnable == "Once") -+ { -+ oneTimeSetting = true; -+ } -+ else if (*bootEnable == "Continuous") -+ { -+ oneTimeSetting = false; -+ } -+ else if (*bootEnable == "Disabled") -+ { -+ BMCWEB_LOG_DEBUG << "Boot source override will be disabled"; -+ oneTimeSetting = false; -+ overrideEnabled = false; -+ } -+ else -+ { -+ BMCWEB_LOG_DEBUG << "Unsupported value for " -+ "BootSourceOverrideEnabled: " -+ << *bootEnable; -+ messages::propertyValueNotInList( -+ aResp->res, *bootEnable, "BootSourceOverrideEnabled"); -+ return; -+ } -+ } -+ -+ std::string bootObj = "/xyz/openbmc_project/control/host0/boot"; -+ if (oneTimeSetting) -+ { -+ bootObj += "/one_time"; -+ } -+ -+ setBootModeOrSource(aResp, overrideEnabled, bootObj, bootSource); -+ setBootType(aResp, overrideEnabled, bootObj, bootType); -+ setOneTime(aResp, oneTimeSetting); -+ }, -+ "xyz.openbmc_project.Settings", -+ "/xyz/openbmc_project/control/host0/boot/one_time", -+ "org.freedesktop.DBus.Properties", "Get", -+ "xyz.openbmc_project.Object.Enable", "Enabled"); - } - - /** -@@ -2806,11 +2803,11 @@ inline void requestRoutesSystems(App& app) - { - return; - } -- - if (bootSource || bootType || bootEnable) - { -- setBootProperties(asyncResp, bootSource, bootType, -- bootEnable); -+ setBootSourceProperties( -+ asyncResp, std::move(bootSource), -+ std::move(bootType), std::move(bootEnable)); - } - if (automaticRetryConfig) - { --- -2.17.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0003-Add-support-to-ResetBios-action.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0003-Add-support-to-ResetBios-action.patch index 028d09e74..a5c55afd1 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0003-Add-support-to-ResetBios-action.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0003-Add-support-to-ResetBios-action.patch @@ -1,31 +1,25 @@ -From 02e44acef17a2b0681fe019e090d09015f9412e0 Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -Date: Wed, 30 Jun 2021 15:27:16 +0000 -Subject: [PATCH 3/5] Add support to ResetBios action +From 415b5079ff45c1dabad15e0f751001a6265412e4 Mon Sep 17 00:00:00 2001 +From: AppaRao Puli +Date: Fri, 27 Aug 2021 13:02:20 +0000 +Subject: [PATCH] Add support to ResetBios action Tested: Bios reset flag can be modified throw redfish POST https://IP_ADDR/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios -Change-Id: I5e5fbdd70d4a3ce3b976cc2eb0a7d9a2a3adb124 +Change-Id: Ic719c55705e5f634539b3dd858b60922e505a8d0 Signed-off-by: Kuiying Wang +Signed-off-by: AppaRao Puli --- - redfish-core/lib/bios.hpp | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) + redfish-core/lib/bios.hpp | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp -index 14d2171..49c0fd0 100644 +index 85ccaaa..360a749 100644 --- a/redfish-core/lib/bios.hpp +++ b/redfish-core/lib/bios.hpp -@@ -665,24 +665,28 @@ inline void requestRoutesBiosAttributeRegistry(App& app) - inline void requestRoutesBiosReset(App& app) - { - BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios/") -- // Incorrect Privilege; Should be ConfigureComponents -- //.privileges(redfish::privileges::postBios) -- .privileges({{"ConfigureManager"}}) -+ .privileges(redfish::privileges::postBios) +@@ -737,18 +737,24 @@ inline void requestRoutesBiosReset(App& app) .methods(boost::beast::http::verb::post)( [](const crow::Request&, const std::shared_ptr& asyncResp) { diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0004-Add-Server-Sent-Events-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0004-Add-Server-Sent-Events-support.patch index 64948ca0c..da281467e 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0004-Add-Server-Sent-Events-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0004-Add-Server-Sent-Events-support.patch @@ -1,4 +1,4 @@ -From 882dc7755083eea32f3d14f7e6c7330d5a9ac66f Mon Sep 17 00:00:00 2001 +From 54bdd897bd416fef4c043224b398b1b6d47fd271 Mon Sep 17 00:00:00 2001 From: AppaRao Puli Date: Fri, 12 Mar 2021 18:53:25 +0000 Subject: [PATCH] Add Server-Sent-Events support @@ -30,10 +30,10 @@ Signed-off-by: AppaRao Puli create mode 100644 http/server_sent_event.hpp diff --git a/http/http_connection.hpp b/http/http_connection.hpp -index fb64014..45b1a68 100644 +index a1a7045..90535c5 100644 --- a/http/http_connection.hpp +++ b/http/http_connection.hpp -@@ -326,7 +326,7 @@ class Connection : +@@ -331,7 +331,7 @@ class Connection : BMCWEB_LOG_INFO << "Request: " << " " << this << " HTTP/" << req->version() / 10 << "." << req->version() % 10 << ' ' << req->methodString() @@ -42,10 +42,10 @@ index fb64014..45b1a68 100644 needToCallAfterHandlers = false; -@@ -345,11 +345,15 @@ class Connection : +@@ -350,11 +350,15 @@ class Connection : boost::asio::post(self->adaptor.get_executor(), [self] { self->completeRequest(); }); - }; + }); - if (req->isUpgrade() && - boost::iequals( - req->getHeaderValue(boost::beast::http::field::upgrade), @@ -63,7 +63,7 @@ index fb64014..45b1a68 100644 // delete lambda with self shared_ptr // to enable connection destruction diff --git a/http/http_response.hpp b/http/http_response.hpp -index 72ff9e9..6bb3aa5 100644 +index a983d4a..07b0265 100644 --- a/http/http_response.hpp +++ b/http/http_response.hpp @@ -15,10 +15,15 @@ namespace crow @@ -82,7 +82,7 @@ index 72ff9e9..6bb3aa5 100644 using response_type = boost::beast::http::response; -@@ -138,8 +143,8 @@ struct Response +@@ -143,8 +148,8 @@ struct Response private: bool completed{}; @@ -93,7 +93,7 @@ index 72ff9e9..6bb3aa5 100644 // In case of a JSON object, set the Content-Type header void jsonMode() diff --git a/http/routing.hpp b/http/routing.hpp -index af6269e..318fcfe 100644 +index d2a10b2..25e4ce8 100644 --- a/http/routing.hpp +++ b/http/routing.hpp @@ -6,6 +6,7 @@ @@ -474,4 +474,5 @@ index 0000000..41d18ed +}; +} // namespace crow -- -2.25.1 +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0005-Add-SSE-style-subscription-support-to-eventservice.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0005-Add-SSE-style-subscription-support-to-eventservice.patch index 78b52eea1..42a1ebbf0 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0005-Add-SSE-style-subscription-support-to-eventservice.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0005-Add-SSE-style-subscription-support-to-eventservice.patch @@ -1,4 +1,4 @@ -From a9d994919b677a2650b80fb449cf96baad4f04dd Mon Sep 17 00:00:00 2001 +From 36c1391749e19e4a25ca6e57d369457f48e6bb11 Mon Sep 17 00:00:00 2001 From: AppaRao Puli Date: Tue, 16 Mar 2021 15:37:24 +0000 Subject: [PATCH] Add SSE style subscription support to eventservice @@ -19,23 +19,24 @@ Tested: - Ran RedfishValidation and its passed. Signed-off-by: AppaRao Puli +Signed-off-by: Nitin Wankhade Change-Id: I7f4b7a34974080739c4ba968ed570489af0474de --- http/http_connection.hpp | 2 +- include/eventservice_sse.hpp | 75 +++++ - .../include/event_service_manager.hpp | 109 +++++-- + .../include/event_service_manager.hpp | 111 +++++-- redfish-core/include/server_sent_events.hpp | 290 ------------------ redfish-core/lib/event_service.hpp | 8 +- src/webserver_main.cpp | 2 + - 6 files changed, 164 insertions(+), 322 deletions(-) + 6 files changed, 165 insertions(+), 323 deletions(-) create mode 100644 include/eventservice_sse.hpp delete mode 100644 redfish-core/include/server_sent_events.hpp diff --git a/http/http_connection.hpp b/http/http_connection.hpp -index 45b1a68bf015..ccc2d6a753b7 100644 +index 90535c5..37c0a0b 100644 --- a/http/http_connection.hpp +++ b/http/http_connection.hpp -@@ -350,7 +350,7 @@ class Connection : +@@ -355,7 +355,7 @@ class Connection : boost::iequals(req->getHeaderValue( boost::beast::http::field::upgrade), "websocket")) || @@ -46,7 +47,7 @@ index 45b1a68bf015..ccc2d6a753b7 100644 << " is getting upgraded"; diff --git a/include/eventservice_sse.hpp b/include/eventservice_sse.hpp new file mode 100644 -index 000000000000..14daf00852f5 +index 0000000..14daf00 --- /dev/null +++ b/include/eventservice_sse.hpp @@ -0,0 +1,75 @@ @@ -126,7 +127,7 @@ index 000000000000..14daf00852f5 +} // namespace eventservice_sse +} // namespace redfish diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index ca46aa7dc62f..098134a3a259 100644 +index ca46aa7..9397271 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -22,15 +22,17 @@ @@ -216,23 +217,23 @@ index ca46aa7dc62f..098134a3a259 100644 ~Subscription() = default; -@@ -417,7 +417,7 @@ class Subscription : public persistent_data::UserSubscription +@@ -412,13 +412,14 @@ class Subscription : public persistent_data::UserSubscription + } + conn->addHeaders(reqHeaders); + conn->sendData(msg); +- this->eventSeqNum++; + } if (sseConn != nullptr) { - sseConn->sendData(eventSeqNum, msg); + sseConn->sendEvent(std::to_string(eventSeqNum), msg); } - } - -@@ -508,6 +508,7 @@ class Subscription : public persistent_data::UserSubscription - - this->sendEvent( - msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); ++ + this->eventSeqNum++; } - #endif + void sendTestEventLog() @@ -578,14 +579,39 @@ class Subscription : public persistent_data::UserSubscription return eventSeqNum; } @@ -326,7 +327,7 @@ index ca46aa7dc62f..098134a3a259 100644 std::vector idList; diff --git a/redfish-core/include/server_sent_events.hpp b/redfish-core/include/server_sent_events.hpp deleted file mode 100644 -index 7613d7ba6427..000000000000 +index 7613d7b..0000000 --- a/redfish-core/include/server_sent_events.hpp +++ /dev/null @@ -1,290 +0,0 @@ @@ -621,7 +622,7 @@ index 7613d7ba6427..000000000000 - -} // namespace crow diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp -index f1d6f5007d79..4a2d58a2f1dd 100644 +index 67ad014..f8a2dac 100644 --- a/redfish-core/lib/event_service.hpp +++ b/redfish-core/lib/event_service.hpp @@ -37,8 +37,6 @@ static constexpr const std::array supportedResourceTypes = { @@ -654,7 +655,7 @@ index f1d6f5007d79..4a2d58a2f1dd 100644 std::optional retryAttemps; std::optional retryInterval; diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp -index c01accd2e93e..363005105d18 100644 +index bf98aae..53745d8 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -6,6 +6,7 @@ @@ -662,10 +663,10 @@ index c01accd2e93e..363005105d18 100644 #include #include +#include + #include #include #include - #include -@@ -82,6 +83,7 @@ int main(int /*argc*/, char** /*argv*/) +@@ -83,6 +84,7 @@ int main(int /*argc*/, char** /*argv*/) #endif #ifdef BMCWEB_ENABLE_REDFISH diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch index 79b6e42d7..9043bd0b9 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch @@ -1,4 +1,4 @@ -From e8bf93f1cc374a986896174489719065d0cc49a0 Mon Sep 17 00:00:00 2001 +From 22c6b6cfb468f8de9ff3ea051dffdba05778645e Mon Sep 17 00:00:00 2001 From: AppaRao Puli Date: Wed, 17 Mar 2021 01:16:50 +0000 Subject: [PATCH] Add EventService SSE filter support @@ -223,10 +223,10 @@ index 10567d1..f29e326 100644 } // namespace redfish diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index 098134a..c8fcb33 100644 +index 5886d81..c3e7f61 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp -@@ -55,6 +55,11 @@ static constexpr const char* eventServiceFile = +@@ -56,6 +56,11 @@ static constexpr const char* eventServiceFile = static constexpr const uint8_t maxNoOfSubscriptions = 20; static constexpr const uint8_t maxNoOfSSESubscriptions = 10; @@ -239,10 +239,10 @@ index 098134a..c8fcb33 100644 static std::optional inotifyConn; static constexpr const char* redfishEventLogDir = "/var/log"; diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp -index 4a2d58a..67abb95 100644 +index 2e7c3f3..9def549 100644 --- a/redfish-core/lib/event_service.hpp +++ b/redfish-core/lib/event_service.hpp -@@ -21,11 +21,6 @@ +@@ -25,11 +25,6 @@ namespace redfish { diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0007-EventService-Log-events-for-subscription-actions.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0007-EventService-Log-events-for-subscription-actions.patch index 7749ddb72..3be65ee2a 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0007-EventService-Log-events-for-subscription-actions.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0007-EventService-Log-events-for-subscription-actions.patch @@ -1,6 +1,6 @@ -From dad35d6e6736f1c4ab6d739c62b22923ad749ad7 Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -Date: Tue, 13 Jul 2021 12:30:08 +0000 +From b8eb53886106e44e3668857b13f8642d2ad3cfbf Mon Sep 17 00:00:00 2001 +From: AppaRao Puli +Date: Fri, 27 Aug 2021 16:02:01 +0000 Subject: [PATCH] EventService: Log events for subscription actions Log redfish event for below 3 actions @@ -18,7 +18,7 @@ Tested: - Performed all the above actions and verified the redfish event messages are logged. -Change-Id: I528293e55b1f3401bc2bb09c11c63ae985fbfedb +Change-Id: I3745fa6357bd215379781a9818d9acc02a853d79 Signed-off-by: AppaRao Puli Signed-off-by: Ayushi Smriti --- @@ -27,10 +27,10 @@ Signed-off-by: Ayushi Smriti 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index a5b37e5..75f5615 100644 +index c3e7f61..e9bdbfa 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp -@@ -20,6 +20,7 @@ +@@ -21,6 +21,7 @@ #include "registries/task_event_message_registry.hpp" #include @@ -38,16 +38,16 @@ index a5b37e5..75f5615 100644 #include #include -@@ -813,7 +814,7 @@ class EventServiceManager - return; +@@ -788,7 +789,7 @@ class EventServiceManager + } } - void updateSubscriptionData() + void persistSubscriptionData() { - // Persist the config and subscription data. - nlohmann::json jsonData; -@@ -910,7 +911,7 @@ class EventServiceManager + persistent_data::EventServiceStore::getInstance() + .eventServiceConfig.enabled = serviceEnabled; +@@ -835,7 +836,7 @@ class EventServiceManager if (updateConfig) { @@ -56,7 +56,7 @@ index a5b37e5..75f5615 100644 } if (updateRetryCfg) -@@ -1005,7 +1006,7 @@ class EventServiceManager +@@ -947,7 +948,7 @@ class EventServiceManager if (updateFile) { @@ -65,7 +65,7 @@ index a5b37e5..75f5615 100644 } #ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES -@@ -1020,6 +1021,13 @@ class EventServiceManager +@@ -962,6 +963,13 @@ class EventServiceManager // Set Subscription ID for back trace subValue->setSubscriptionId(id); @@ -79,9 +79,9 @@ index a5b37e5..75f5615 100644 return id; } -@@ -1040,7 +1048,14 @@ class EventServiceManager - { - subscriptionsMap.erase(obj); +@@ -986,7 +994,14 @@ class EventServiceManager + persistent_data::EventServiceStore::getInstance() + .subscriptionsConfigMap.erase(obj2); updateNoOfSubscribersCount(); - updateSubscriptionData(); + @@ -95,7 +95,7 @@ index a5b37e5..75f5615 100644 } } -@@ -1062,6 +1077,18 @@ class EventServiceManager +@@ -1008,6 +1023,18 @@ class EventServiceManager } } @@ -115,10 +115,10 @@ index a5b37e5..75f5615 100644 { return subscriptionsMap.size(); diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp -index 53a60d3..435c93d 100644 +index 9def549..6a8421f 100644 --- a/redfish-core/lib/event_service.hpp +++ b/redfish-core/lib/event_service.hpp -@@ -579,7 +579,7 @@ inline void requestRoutesEventDestination(App& app) +@@ -617,7 +617,7 @@ inline void requestRoutesEventDestination(App& app) subValue->updateRetryPolicy(); } @@ -126,7 +126,7 @@ index 53a60d3..435c93d 100644 + EventServiceManager::getInstance().updateSubscription(param); }); BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions//") - .privileges({{"ConfigureManager"}}) + // The below privilege is wrong, it should be ConfigureManager OR -- -2.25.1 +2.17.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0009-Restructure-Redifsh-EventLog-Transmit-code-flow.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0009-Restructure-Redifsh-EventLog-Transmit-code-flow.patch index 6e635a828..d1fe475f5 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0009-Restructure-Redifsh-EventLog-Transmit-code-flow.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0009-Restructure-Redifsh-EventLog-Transmit-code-flow.patch @@ -1,4 +1,4 @@ -From 7f45c83c0b3acb08461461c23e0d7add46d9191c Mon Sep 17 00:00:00 2001 +From 542505dff60e3921b00b51acae882e207d46f1a6 Mon Sep 17 00:00:00 2001 From: Krzysztof Grobelny Date: Wed, 14 Jul 2021 14:13:11 +0000 Subject: [PATCH] Restructure Redfish EventLog Transmit code flow @@ -35,10 +35,10 @@ Signed-off-by: P Dheeraj Srujan Kumar 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index 430767a..53ed3f6 100644 +index e9bdbfa..5c4de70 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp -@@ -133,15 +133,10 @@ static const Message* formatMessage(const std::string_view& messageID) +@@ -134,15 +134,10 @@ static const Message* formatMessage(const std::string_view& messageID) namespace event_log { @@ -55,7 +55,7 @@ index 430767a..53ed3f6 100644 // Get the entry timestamp std::time_t curTs = 0; -@@ -639,6 +634,7 @@ class EventServiceManager +@@ -621,6 +616,7 @@ class EventServiceManager } std::string lastEventTStr; @@ -63,7 +63,7 @@ index 430767a..53ed3f6 100644 size_t noOfEventLogSubscribers{0}; size_t noOfMetricReportSubscribers{0}; std::shared_ptr matchTelemetryMonitor; -@@ -1204,7 +1200,22 @@ class EventServiceManager +@@ -1163,7 +1159,22 @@ class EventServiceManager #ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES void cacheLastEventTimestamp() { @@ -87,7 +87,7 @@ index 430767a..53ed3f6 100644 std::ifstream logStream(redfishEventLogFile); if (!logStream.good()) { -@@ -1212,27 +1223,44 @@ class EventServiceManager +@@ -1171,27 +1182,44 @@ class EventServiceManager return; } std::string logEntry; @@ -143,7 +143,7 @@ index 430767a..53ed3f6 100644 std::ifstream logStream(redfishEventLogFile); if (!logStream.good()) { -@@ -1242,27 +1270,21 @@ class EventServiceManager +@@ -1201,27 +1229,21 @@ class EventServiceManager std::vector eventRecords; @@ -178,7 +178,7 @@ index 430767a..53ed3f6 100644 std::string timestamp; std::string messageID; -@@ -1274,6 +1296,16 @@ class EventServiceManager +@@ -1233,6 +1255,16 @@ class EventServiceManager continue; } @@ -195,7 +195,7 @@ index 430767a..53ed3f6 100644 std::string registryName; std::string messageKey; event_log::getRegistryAndMessageKey(messageID, registryName, -@@ -1283,11 +1315,23 @@ class EventServiceManager +@@ -1242,11 +1274,23 @@ class EventServiceManager continue; } @@ -221,5 +221,5 @@ index 430767a..53ed3f6 100644 { std::shared_ptr entry = it.second; -- -2.25.1 +2.17.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch index f53b7013f..c19691cdc 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch @@ -1,12 +1,20 @@ -From e37e30943fcb1ba504658ed07d69f950ccf44585 Mon Sep 17 00:00:00 2001 +From 80608f0d72da62426bb00e03a42fbf5daed931c9 Mon Sep 17 00:00:00 2001 From: Krzysztof Grobelny Date: Tue, 13 Apr 2021 13:00:18 +0000 Subject: [PATCH] Add support for MetricDefinition scheme Added MetricDefinition node to Redfish code. Now user is able to list all available metrics in OpenBMC that are supported by Telemetry -service. Metrics are grouped by following categories: temperature, -power, voltage, current, fan_tach, fan_pwm, utilization. +service. Metrics are grouped by reading type. + +MetricDefinitions contains all physical sensors supported by redfish, +algorithm iterates through all chassis and collects results for each +node available in that chassis (Power, Thermal, Sensors). + +When https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/40169 will +be merge it will be possible to optimize this algorithm to only get +sensors from Sensors node. Currently Sensors node doesn't contain all +available sensors. Tested: - MetricDefinitions response is filled with existing sensors, it works @@ -14,18 +22,98 @@ Tested: - Validated a presence of MetricDefinition members and its attributes - Successfully passed RedfishServiceValidator.py using witherspoon image on QEMU + - Tested using following GET,POST requests + +GET /redfish/v1/TelemetryService/MetricDefinitions +{ + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions", + "@odata.type": "#MetricDefinitionCollection.MetricDefinitionCollection", + "Members": [ + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Rotational" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Percent" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Temperature" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Power" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/AirFlow" + } + ], + "Members@odata.count": 5, + "Name": "Metric Definition Collection" +} + +GET /redfish/v1/TelemetryService/MetricDefinitions/Rotational +{ + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Rotational", + "@odata.type": "#MetricDefinition.v1_0_3.MetricDefinition", + "Id": "Rotational", + "Implementation": "PhysicalSensor", + "IsLinear": true, + "MetricDataType": "Decimal", + "MetricProperties": [ + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/0/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/1/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/2/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/4/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/5/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/6/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/7/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/8/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/9/Reading" + ], + "MetricType": "Numeric", + "Name": "Rotational", + "Units": "RPM" +} + +POST redfish/v1/TelemetryService/MetricReportDefinitions, body: +{ + "Id": "TestReport", + "Metrics": [ + { + "MetricId": "TestMetric", + "MetricProperties": [ + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading", + ] + } + ], + "MetricReportDefinitionType": "OnRequest", + "ReportActions": [ + "RedfishEvent", + "LogToMetricReportsCollection" + ] +} +{ + "@Message.ExtendedInfo": [ + { + "@odata.type": "#Message.v1_1_1.Message", + "Message": "The resource has been created successfully", + "MessageArgs": [], + "MessageId": "Base.1.8.1.Created", + "MessageSeverity": "OK", + "Resolution": "None" + } + ] +} Signed-off-by: Wludzik, Jozef Signed-off-by: Krzysztof Grobelny Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00 --- redfish-core/include/redfish.hpp | 3 + - .../include/utils/get_chassis_names.hpp | 58 +++++ + .../include/utils/get_chassis_names.hpp | 58 ++++ .../include/utils/telemetry_utils.hpp | 2 + - redfish-core/lib/metric_definition.hpp | 242 ++++++++++++++++++ - redfish-core/lib/sensors.hpp | 25 +- + redfish-core/lib/metric_definition.hpp | 258 ++++++++++++++++++ redfish-core/lib/telemetry_service.hpp | 2 + - 6 files changed, 320 insertions(+), 12 deletions(-) + 5 files changed, 323 insertions(+) create mode 100644 redfish-core/include/utils/get_chassis_names.hpp create mode 100644 redfish-core/lib/metric_definition.hpp @@ -129,10 +217,10 @@ index 5872350..1b4f75d 100644 constexpr const char* metricReportUri = diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp new file mode 100644 -index 0000000..2443996 +index 0000000..019168b --- /dev/null +++ b/redfish-core/lib/metric_definition.hpp -@@ -0,0 +1,242 @@ +@@ -0,0 +1,258 @@ +#pragma once + +#include "async_resp.hpp" @@ -140,12 +228,34 @@ index 0000000..2443996 +#include "utils/get_chassis_names.hpp" +#include "utils/telemetry_utils.hpp" + ++#include ++ +namespace redfish +{ + +namespace telemetry +{ + ++bool containsOdata(const nlohmann::json& json, const std::string& odataId) ++{ ++ const auto it = std::find_if( ++ json.begin(), json.end(), [&odataId](const nlohmann::json& item) { ++ auto kt = item.find("@odata.id"); ++ if (kt == item.end()) ++ { ++ return false; ++ } ++ const std::string* value = kt->get_ptr(); ++ if (!value) ++ { ++ return false; ++ } ++ return *value == odataId; ++ }); ++ ++ return it != json.end(); ++} ++ +void addMembers(crow::Response& res, + const boost::container::flat_map& el) +{ @@ -168,23 +278,7 @@ index 0000000..2443996 + std::string(telemetry::metricDefinitionUri) + + sensors::toReadingType(type); + -+ const auto it = std::find_if(members.begin(), members.end(), -+ [&odataId](const nlohmann::json& item) { -+ auto kt = item.find("@odata.id"); -+ if (kt == item.end()) -+ { -+ return false; -+ } -+ const std::string* value = -+ kt->get_ptr(); -+ if (!value) -+ { -+ return false; -+ } -+ return *value == odataId; -+ }); -+ -+ if (it == members.end()) ++ if (!containsOdata(members, odataId)) + { + members.push_back({{"@odata.id", odataId}}); + } @@ -193,15 +287,76 @@ index 0000000..2443996 + } +} + ++template ++inline void mapRedfishUriToDbusPath(Callback&& callback) ++{ ++ utils::getChassisNames([callback = std::move(callback)]( ++ boost::system::error_code ec, ++ const std::vector& chassisNames) { ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "getChassisNames error: " << ec.value(); ++ callback(ec, {}); ++ return; ++ } ++ ++ auto handleRetrieveUriToDbusMap = ++ [callback = std::move(callback)]( ++ const boost::beast::http::status status, ++ const boost::container::flat_map& ++ uriToDbus) { ++ if (status != boost::beast::http::status::ok) ++ { ++ BMCWEB_LOG_ERROR << "Failed to retrieve URI to dbus " ++ "sensors map with err " ++ << static_cast(status); ++ callback(boost::system::errc::make_error_code( ++ boost::system::errc::io_error), ++ {}); ++ return; ++ } ++ ++ callback(boost::system::errc::make_error_code( ++ boost::system::errc::success), ++ uriToDbus); ++ }; ++ ++ for (const std::string& chassisName : chassisNames) ++ { ++ for (const auto& [sensorNode, dbusPaths] : sensors::dbus::paths) ++ { ++ retrieveUriToDbusMap(chassisName, sensorNode.data(), ++ handleRetrieveUriToDbusMap); ++ } ++ } ++ }); ++} ++ +} // namespace telemetry + +inline void requestRoutesMetricDefinitionCollection(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions/") -+ .privileges({{"Login"}}) ++ .privileges(privileges::getTelemetryService) + .methods(boost::beast::http::verb::get)( + [](const crow::Request&, + const std::shared_ptr& asyncResp) { ++ telemetry::mapRedfishUriToDbusPath( ++ [asyncResp](boost::system::error_code ec, ++ const boost::container::flat_map< ++ std::string, std::string>& uriToDbus) { ++ if (ec) ++ { ++ messages::internalError(asyncResp->res); ++ BMCWEB_LOG_ERROR ++ << "mapRedfishUriToDbusPath error: " ++ << ec.value(); ++ return; ++ } ++ ++ telemetry::addMembers(asyncResp->res, uriToDbus); ++ }); ++ + asyncResp->res.jsonValue["@odata.type"] = + "#MetricDefinitionCollection." + "MetricDefinitionCollection"; @@ -211,49 +366,6 @@ index 0000000..2443996 + "Metric Definition Collection"; + asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); + asyncResp->res.jsonValue["Members@odata.count"] = 0; -+ -+ utils::getChassisNames( -+ [asyncResp](boost::system::error_code ec, -+ const std::vector& chassisNames) { -+ if (ec) -+ { -+ messages::internalError(asyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " -+ << ec.value(); -+ return; -+ } -+ -+ auto handleRetrieveUriToDbusMap = -+ [asyncResp]( -+ const boost::beast::http::status status, -+ const boost::container::flat_map< -+ std::string, std::string>& uriToDbus) { -+ if (status != boost::beast::http::status::ok) -+ { -+ BMCWEB_LOG_ERROR -+ << "Failed to retrieve URI to dbus " -+ "sensors map with err " -+ << static_cast(status); -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ telemetry::addMembers(asyncResp->res, -+ uriToDbus); -+ }; -+ -+ for (const std::string& chassisName : chassisNames) -+ { -+ for (const auto& [sensorNode, _] : -+ sensors::dbus::paths) -+ { -+ BMCWEB_LOG_DEBUG << "Chassis: " << chassisName -+ << " sensor: " << sensorNode; -+ retrieveUriToDbusMap( -+ chassisName, sensorNode.data(), -+ handleRetrieveUriToDbusMap); -+ } -+ } -+ }); + }); +} + @@ -298,12 +410,29 @@ index 0000000..2443996 + } +} + ++inline const char* readingTypeToReadingUnits(const std::string& readingType) ++{ ++ for (const auto& [node, paths] : sensors::dbus::paths) ++ { ++ for (const char* path : paths) ++ { ++ const sdbusplus::message::object_path sensorPath = ++ sdbusplus::message::object_path(path); ++ if (sensors::toReadingType(sensorPath.filename()) == readingType) ++ { ++ return sensors::toReadingUnits(sensorPath.filename()); ++ } ++ } ++ } ++ return ""; ++} ++ +} // namespace telemetry + +inline void requestRoutesMetricDefinition(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions//") -+ .privileges({{"Login"}}) ++ .privileges(privileges::getTelemetryService) + .methods(boost::beast::http::verb::get)( + [](const crow::Request&, + const std::shared_ptr& asyncResp, @@ -315,142 +444,41 @@ index 0000000..2443996 + return; + } + -+ asyncResp->res.jsonValue["MetricProperties"] = -+ nlohmann::json::array(); -+ asyncResp->res.jsonValue["Id"] = readingType; -+ asyncResp->res.jsonValue["Name"] = readingType; -+ asyncResp->res.jsonValue["@odata.id"] = -+ telemetry::metricDefinitionUri + readingType; -+ asyncResp->res.jsonValue["@odata.type"] = -+ "#MetricDefinition.v1_0_3.MetricDefinition"; -+ asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; -+ asyncResp->res.jsonValue["MetricType"] = "Numeric"; -+ asyncResp->res.jsonValue["IsLinear"] = true; -+ asyncResp->res.jsonValue["Implementation"] = "PhysicalSensor"; -+ asyncResp->res.jsonValue["Units"] = -+ sensors::toReadingUnits(readingType); -+ -+ utils::getChassisNames( -+ [asyncResp, readingType]( -+ boost::system::error_code ec, -+ const std::vector& chassisNames) { ++ telemetry::mapRedfishUriToDbusPath( ++ [asyncResp, ++ readingType](boost::system::error_code ec, ++ const boost::container::flat_map< ++ std::string, std::string>& uriToDbus) { + if (ec) + { + messages::internalError(asyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " -+ << ec.value(); ++ BMCWEB_LOG_ERROR ++ << "mapRedfishUriToDbusPath error: " ++ << ec.value(); + return; + } + -+ auto handleRetrieveUriToDbusMap = -+ [asyncResp, readingType]( -+ const boost::beast::http::status status, -+ const boost::container::flat_map< -+ std::string, std::string>& uriToDbus) { -+ if (status != boost::beast::http::status::ok) -+ { -+ BMCWEB_LOG_ERROR -+ << "Failed to retrieve URI to dbus " -+ "sensors map with err " -+ << static_cast(status); -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ telemetry::addMetricProperty( -+ *asyncResp, readingType, uriToDbus); -+ }; -+ -+ for (const std::string& chassisName : chassisNames) -+ { -+ for (const auto& [sensorNode, dbusPaths] : -+ sensors::dbus::paths) -+ { -+ retrieveUriToDbusMap( -+ chassisName, sensorNode.data(), -+ handleRetrieveUriToDbusMap); -+ } -+ } ++ asyncResp->res.jsonValue["Id"] = readingType; ++ asyncResp->res.jsonValue["Name"] = readingType; ++ asyncResp->res.jsonValue["@odata.id"] = ++ telemetry::metricDefinitionUri + readingType; ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#MetricDefinition.v1_0_3.MetricDefinition"; ++ asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; ++ asyncResp->res.jsonValue["MetricType"] = "Numeric"; ++ asyncResp->res.jsonValue["IsLinear"] = true; ++ asyncResp->res.jsonValue["Implementation"] = ++ "PhysicalSensor"; ++ asyncResp->res.jsonValue["Units"] = ++ telemetry::readingTypeToReadingUnits(readingType); ++ ++ telemetry::addMetricProperty(*asyncResp, readingType, ++ uriToDbus); + }); + }); +} + +} // namespace redfish -diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp -index d986565..bccbb94 100644 ---- a/redfish-core/lib/sensors.hpp -+++ b/redfish-core/lib/sensors.hpp -@@ -111,46 +111,47 @@ inline const char* toReadingType(const std::string& sensorType) - return ""; - } - --inline const char* toReadingUnits(const std::string& sensorType) -+inline const char* toReadingUnits(const std::string& readingType) - { -- if (sensorType == "voltage") -+ if (readingType == "Voltage") - { - return "V"; - } -- if (sensorType == "power") -+ if (readingType == "Power") - { - return "W"; - } -- if (sensorType == "current") -+ if (readingType == "Current") - { - return "A"; - } -- if (sensorType == "fan_tach") -+ if (readingType == "Rotational") - { - return "RPM"; - } -- if (sensorType == "temperature") -+ if (readingType == "Temperature") - { - return "Cel"; - } -- if (sensorType == "fan_pwm" || sensorType == "utilization") -+ if (readingType == "Percent") - { - return "%"; - } -- if (sensorType == "altitude") -+ if (readingType == "Altitude") - { - return "m"; - } -- if (sensorType == "airflow") -+ if (readingType == "AirFlow") - { - return "cft_i/min"; - } -- if (sensorType == "energy") -+ if (readingType == "EnergyJoules") - { - return "J"; - } - return ""; - } -+ - } // namespace sensors - - /** -@@ -953,11 +954,11 @@ inline void objectInterfacesToJson( - sensorJson["ReadingType"] = readingType; - } - -- const std::string& readingUnits = sensors::toReadingUnits(sensorType); -+ const std::string& readingUnits = sensors::toReadingUnits(readingType); - if (readingUnits.empty()) - { - BMCWEB_LOG_ERROR << "Redfish cannot map reading unit for " -- << sensorType; -+ << readingType; - } - else - { diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp index ad86d5c..c4962e9 100644 --- a/redfish-core/lib/telemetry_service.hpp diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch index 0ca58a114..d32c85356 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch @@ -1,4 +1,4 @@ -From 277d261ef3b1723c9d198baf4b84d2e01a7460b8 Mon Sep 17 00:00:00 2001 +From 77e8a0b5037a555b1520823b667595ac8780c675 Mon Sep 17 00:00:00 2001 From: "Wludzik, Jozef" Date: Tue, 15 Dec 2020 12:30:31 +0100 Subject: [PATCH] Sync Telmetry service with EventService @@ -22,7 +22,7 @@ Signed-off-by: Wludzik, Jozef 2 files changed, 69 insertions(+), 115 deletions(-) diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index 11190ef..ffe9435 100644 +index d89b789..4faaddd 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -14,6 +14,7 @@ @@ -33,7 +33,7 @@ index 11190ef..ffe9435 100644 #include "registries.hpp" #include "registries/base_message_registry.hpp" #include "registries/openbmc_message_registry.hpp" -@@ -522,47 +523,32 @@ class Subscription +@@ -511,47 +512,32 @@ class Subscription : public persistent_data::UserSubscription } #endif @@ -92,7 +92,7 @@ index 11190ef..ffe9435 100644 this->sendEvent( msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); } -@@ -1358,75 +1344,6 @@ class EventServiceManager +@@ -1317,75 +1303,6 @@ class EventServiceManager } #endif @@ -168,7 +168,7 @@ index 11190ef..ffe9435 100644 void unregisterMetricReportSignal() { if (matchTelemetryMonitor) -@@ -1446,9 +1363,11 @@ class EventServiceManager +@@ -1405,9 +1322,11 @@ class EventServiceManager } BMCWEB_LOG_DEBUG << "Metrics report signal - Register"; @@ -183,7 +183,7 @@ index 11190ef..ffe9435 100644 matchTelemetryMonitor = std::make_shared( *crow::connections::systemBus, matchStr, -@@ -1459,10 +1378,43 @@ class EventServiceManager +@@ -1418,10 +1337,43 @@ class EventServiceManager return; } @@ -232,10 +232,10 @@ index 11190ef..ffe9435 100644 } diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp -index 66f4f93..a43f6a6 100644 +index 63c8c19..7fe281d 100644 --- a/redfish-core/lib/metric_report.hpp +++ b/redfish-core/lib/metric_report.hpp -@@ -32,16 +32,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) +@@ -33,16 +33,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) return metricValues; } @@ -258,7 +258,7 @@ index 66f4f93..a43f6a6 100644 telemetry::metricReportDefinitionUri + id; const TimestampReadings* timestampReadings = -@@ -49,14 +47,14 @@ inline void fillReport(const std::shared_ptr& asyncResp, +@@ -50,14 +48,14 @@ inline void fillReport(const std::shared_ptr& asyncResp, if (!timestampReadings) { BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; @@ -277,7 +277,7 @@ index 66f4f93..a43f6a6 100644 } } // namespace telemetry -@@ -117,7 +115,11 @@ inline void requestRoutesMetricReport(App& app) +@@ -118,7 +116,11 @@ inline void requestRoutesMetricReport(App& app) return; } diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch deleted file mode 100644 index 987a43b4c..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 472ac5f15a19917042852b243e8b668b3ab49e32 Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -Date: Tue, 22 Jun 2021 13:59:48 +0000 -Subject: [PATCH] Revert "Remove LogService from TelemetryService" - -This reverts commit 2b3da45876aac57a36d3093379a992d699e7e396. ---- - redfish-core/lib/telemetry_service.hpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp -index 37221c3..f3a1efb 100644 ---- a/redfish-core/lib/telemetry_service.hpp -+++ b/redfish-core/lib/telemetry_service.hpp -@@ -30,6 +30,8 @@ inline void requestRoutesTelemetryService(App& app) - "/redfish/v1/TelemetryService/MetricReports"; - asyncResp->res.jsonValue["MetricDefinitions"]["@odata.id"] = - "/redfish/v1/TelemetryService/MetricDefinitions"; -+ asyncResp->res.jsonValue["LogService"]["@odata.id"] = -+ "/redfish/v1/Managers/bmc/LogServices/Journal"; - - crow::connections::systemBus->async_method_call( - [asyncResp]( --- -2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch new file mode 100644 index 000000000..20bcbabfa --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch @@ -0,0 +1,301 @@ +From fca6f5b951a363916a83a25f6578f95a6cf32a3e Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Thu, 17 Jun 2021 13:37:57 +0000 +Subject: [PATCH] Switched bmcweb to use new telemetry service API + +Added support for multiple MetricProperties. Added support for new +parameters: CollectionTimeScope, CollectionDuration. + +Tested: + - It is possible to create MetricReportDefinitions with multiple + MetricProperties. + - Stub values for new parameters are correctly passed to telemetry + service. + - All existing telemetry service functionalities remain unchanged. + +Change-Id: I2cd17069e3ea015c8f5571c29278f1d50536272a +Signed-off-by: Krzysztof Grobelny +--- + redfish-core/lib/metric_report_definition.hpp | 212 ++++++++++-------- + 1 file changed, 114 insertions(+), 98 deletions(-) + +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index a0c4f1d..7c26787 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -7,6 +7,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -17,87 +19,90 @@ namespace redfish + namespace telemetry + { + +-using ReadingParameters = +- std::vector>; ++using ReadingParameters = std::vector< ++ std::tuple, std::string, ++ std::string, std::string, std::string, uint64_t>>; + + inline void fillReportDefinition( + const std::shared_ptr& asyncResp, const std::string& id, + const std::vector< +- std::pair>>& ret) ++ std::pair>>& ++ properties) + { +- asyncResp->res.jsonValue["@odata.type"] = +- "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; +- asyncResp->res.jsonValue["@odata.id"] = +- telemetry::metricReportDefinitionUri + id; +- asyncResp->res.jsonValue["Id"] = id; +- asyncResp->res.jsonValue["Name"] = id; +- asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = +- telemetry::metricReportUri + id; +- asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; +- asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; +- +- const bool* emitsReadingsUpdate = nullptr; +- const bool* logToMetricReportsCollection = nullptr; +- const ReadingParameters* readingParams = nullptr; +- const std::string* reportingType = nullptr; +- const uint64_t* interval = nullptr; +- for (const auto& [key, var] : ret) ++ try + { +- if (key == "EmitsReadingsUpdate") ++ bool emitsReadingsUpdate = false; ++ bool logToMetricReportsCollection = false; ++ ReadingParameters readingParams; ++ std::string reportingType; ++ uint64_t interval = 0u; ++ ++ sdbusplus::unpackProperties( ++ properties, "EmitsReadingsUpdate", emitsReadingsUpdate, ++ "LogToMetricReportsCollection", logToMetricReportsCollection, ++ "ReadingParametersFutureVersion", readingParams, "ReportingType", ++ reportingType, "Interval", interval); ++ ++ std::vector redfishReportActions; ++ redfishReportActions.reserve(2); ++ if (emitsReadingsUpdate) + { +- emitsReadingsUpdate = std::get_if(&var); ++ redfishReportActions.emplace_back("RedfishEvent"); + } +- else if (key == "LogToMetricReportsCollection") ++ if (logToMetricReportsCollection) + { +- logToMetricReportsCollection = std::get_if(&var); ++ redfishReportActions.emplace_back("LogToMetricReportsCollection"); + } +- else if (key == "ReadingParameters") +- { +- readingParams = std::get_if(&var); +- } +- else if (key == "ReportingType") +- { +- reportingType = std::get_if(&var); +- } +- else if (key == "Interval") ++ ++ nlohmann::json metrics = nlohmann::json::array(); ++ for (auto& [sensorPath, operationType, id, metadata, ++ collectionTimeScope, collectionDuration] : readingParams) + { +- interval = std::get_if(&var); ++ std::vector metricProperties; ++ ++ nlohmann::json parsedMetadata = nlohmann::json::parse(metadata); ++ if (!json_util::readJson(parsedMetadata, asyncResp->res, ++ "MetricProperties", metricProperties)) ++ { ++ BMCWEB_LOG_ERROR << "Failed to read metadata"; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ metrics.push_back({ ++ {"MetricId", id}, ++ {"MetricProperties", std::move(metricProperties)}, ++ }); + } +- } +- if (!emitsReadingsUpdate || !logToMetricReportsCollection || +- !readingParams || !reportingType || !interval) +- { +- BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; +- messages::internalError(asyncResp->res); +- return; +- } + +- std::vector redfishReportActions; +- redfishReportActions.reserve(2); +- if (*emitsReadingsUpdate) +- { +- redfishReportActions.emplace_back("RedfishEvent"); ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; ++ asyncResp->res.jsonValue["@odata.id"] = ++ telemetry::metricReportDefinitionUri + id; ++ asyncResp->res.jsonValue["Id"] = id; ++ asyncResp->res.jsonValue["Name"] = id; ++ asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = ++ telemetry::metricReportUri + id; ++ asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; ++ asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; ++ asyncResp->res.jsonValue["Metrics"] = metrics; ++ asyncResp->res.jsonValue["MetricReportDefinitionType"] = reportingType; ++ asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; ++ asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = ++ time_utils::toDurationString(std::chrono::milliseconds(interval)); + } +- if (*logToMetricReportsCollection) ++ catch (const sdbusplus::exception::UnpackPropertyError& error) + { +- redfishReportActions.emplace_back("LogToMetricReportsCollection"); ++ BMCWEB_LOG_ERROR << error.what() << ", property: " ++ << error.propertyName + ", reason: " << error.reason; ++ messages::internalError(asyncResp->res); + } +- +- nlohmann::json metrics = nlohmann::json::array(); +- for (auto& [sensorPath, operationType, id, metadata] : *readingParams) ++ catch (const nlohmann::json::parse_error& e) + { +- metrics.push_back({ +- {"MetricId", id}, +- {"MetricProperties", {metadata}}, +- }); ++ BMCWEB_LOG_ERROR << "Failed to parse metadata: " << e.what(); ++ messages::internalError(asyncResp->res); + } +- asyncResp->res.jsonValue["Metrics"] = metrics; +- asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; +- asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; +- asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = +- time_utils::toDurationString(std::chrono::milliseconds(*interval)); + } + + struct AddReportArgs +@@ -275,6 +280,11 @@ class AddReport + + for (const auto& [id, uris] : args.metrics) + { ++ std::vector dbusPaths; ++ dbusPaths.reserve(uris.size()); ++ nlohmann::json metadata; ++ metadata["MetricProperties"] = nlohmann::json::array(); ++ + for (size_t i = 0; i < uris.size(); i++) + { + const std::string& uri = uris[i]; +@@ -291,8 +301,12 @@ class AddReport + } + + const std::string& dbusPath = el->second; +- readingParams.emplace_back(dbusPath, "SINGLE", id, uri); ++ dbusPaths.emplace_back(dbusPath); ++ metadata["MetricProperties"].emplace_back(uri); + } ++ ++ readingParams.emplace_back(dbusPaths, "SINGLE", id, metadata.dump(), ++ "Point", 0u); + } + const std::shared_ptr aResp = asyncResp; + crow::connections::systemBus->async_method_call( +@@ -330,10 +344,10 @@ class AddReport + messages::created(aResp->res); + }, + telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", +- "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", +- "TelemetryService/" + args.name, args.reportingType, +- args.emitsReadingsUpdate, args.logToMetricReportsCollection, +- args.interval, readingParams); ++ "xyz.openbmc_project.Telemetry.ReportManager", ++ "AddReportFutureVersion", "TelemetryService/" + args.name, ++ args.reportingType, args.emitsReadingsUpdate, ++ args.logToMetricReportsCollection, args.interval, readingParams); + } + + void insert(const boost::container::flat_map& el) +@@ -415,37 +429,39 @@ inline void requestRoutesMetricReportDefinition(App& app) + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions//") + .privileges(redfish::privileges::getMetricReportDefinition) +- .methods(boost::beast::http::verb::get)( +- [](const crow::Request&, +- const std::shared_ptr& asyncResp, +- const std::string& id) { +- crow::connections::systemBus->async_method_call( +- [asyncResp, id]( +- const boost::system::error_code ec, +- const std::vector>>& ret) { +- if (ec.value() == EBADR || +- ec == boost::system::errc::host_unreachable) +- { +- messages::resourceNotFound( +- asyncResp->res, "MetricReportDefinition", id); +- return; +- } +- if (ec) +- { +- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; +- messages::internalError(asyncResp->res); +- return; +- } ++ .methods( ++ boost::beast::http::verb::get)([](const crow::Request&, ++ const std::shared_ptr< ++ bmcweb::AsyncResp>& asyncResp, ++ const std::string& id) { ++ sdbusplus::asio::getAllProperties( ++ *crow::connections::systemBus, telemetry::service, ++ telemetry::getDbusReportPath(id), telemetry::reportInterface, ++ [asyncResp, ++ id](boost::system::error_code ec, ++ const std::vector>>& ++ properties) { ++ if (ec.value() == EBADR || ++ ec == boost::system::errc::host_unreachable) ++ { ++ messages::resourceNotFound( ++ asyncResp->res, "MetricReportDefinition", id); ++ return; ++ } ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ telemetry::fillReportDefinition(asyncResp, id, properties); ++ }); ++ }); + +- telemetry::fillReportDefinition(asyncResp, id, ret); +- }, +- telemetry::service, telemetry::getDbusReportPath(id), +- "org.freedesktop.DBus.Properties", "GetAll", +- telemetry::reportInterface); +- }); + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions//") + .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) +-- +2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch new file mode 100644 index 000000000..3d60ae293 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch @@ -0,0 +1,267 @@ +From 79b3d35b864a2b545b4c9b2ac9390ea5dec169f5 Mon Sep 17 00:00:00 2001 +From: Szymon Dompke +Date: Mon, 28 Jun 2021 11:10:23 +0200 +Subject: [PATCH] Add support for MetricDefinition property in MetricReport + +Added MetricDefinition as part of MetricValues array returned by +MetricReport. It contains single @odata.id with URI to proper +MetricDefinition resource - depending on MetricProperty. + +Testing done: +- GET request on redfish/v1/TelemetryService/MetricReports + got response with MetricDefinition and proper id inside + MetricValues array. + +Testing steps: +1. POST on redfish/v1/TelemetryService/MetricReportDefinitions + with body: +{ + "Id": "PeriodicReport_1", + "MetricReportDefinitionType": "Periodic", + "ReportActions": [ + "LogToMetricReportsCollection", + "RedfishEvent" + ], + "Metrics": [ + { + "MetricId": "sensor_1", + "MetricProperties": [ + "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading" + ] + } + ], + "Schedule": { + "RecurrenceInterval": "PT10S" + } +} + +2. GET on redfish/v1/TelemetryService/MetricReports/PeriodicReport_1 + should return: +{ + "@odata.id": + "/redfish/v1/TelemetryService/MetricReports/PeriodicReport_1", + "@odata.type": "#MetricReport.v1_3_0.MetricReport", + "Id": "PeriodicReport_1", + "MetricReportDefinition": { + "@odata.id": + "/redfish/v1/TelemetryService/MetricReportDefinitions/PeriodicReport_1" + }, + "MetricValues": [ + { + "MetricDefinition": { + "@odata.id": + "/redfish/v1/TelemetryService/MetricDefinitions/Rotational" + }, + "MetricId": "sensor_1", + "MetricProperty": + "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading", + "MetricValue": "nan", + "Timestamp": "1970-01-01T00:03:21+00:00" + } + ], + "Name": "PeriodicReport_1", + "Timestamp": "1970-01-01T00:03:21+00:00" +} + +Change-Id: I7181c612f9b443015d551259bae25303aa436822 +Signed-off-by: Szymon Dompke +--- + meson.build | 4 +- + .../include/utils/telemetry_utils.hpp | 40 ++++++++++++ + redfish-core/lib/metric_report.hpp | 64 +++++++++++++++---- + redfish-core/lib/sensors.hpp | 2 + + 4 files changed, 95 insertions(+), 15 deletions(-) + +diff --git a/meson.build b/meson.build +index f6a66f1..6b5d9af 100644 +--- a/meson.build ++++ b/meson.build +@@ -355,6 +355,8 @@ srcfiles_unittest = ['include/ut/dbus_utility_test.cpp', + 'redfish-core/ut/time_utils_test.cpp', + 'http/ut/utility_test.cpp'] + ++srcfiles_unittest_dependencies = ['redfish-core/src/error_messages.cpp'] ++ + # Gather the Configuration data + + conf_data = configuration_data() +@@ -412,7 +414,7 @@ executable('bmcweb',srcfiles_bmcweb, + if(get_option('tests').enabled()) + foreach src_test : srcfiles_unittest + testname = src_test.split('/')[-1].split('.')[0] +- test(testname,executable(testname,src_test, ++ test(testname,executable(testname,[src_test] + srcfiles_unittest_dependencies, + include_directories : incdir, + install_dir: bindir, + dependencies: [ +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index 1b4f75d..c0c5ba3 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -17,6 +17,46 @@ constexpr const char* metricReportDefinitionUri = + constexpr const char* metricReportUri = + "/redfish/v1/TelemetryService/MetricReports/"; + ++inline std::optional ++ getMetadataJson(const std::string& metadataStr) ++{ ++ std::optional res = ++ nlohmann::json::parse(metadataStr, nullptr, false); ++ if (res->is_discarded()) ++ { ++ BMCWEB_LOG_ERROR << "Malformed reading metatadata JSON provided by " ++ "telemetry service."; ++ return std::nullopt; ++ } ++ return res; ++} ++ ++inline std::optional ++ readStringFromMetadata(const nlohmann::json& metadataJson, const char* key) ++{ ++ std::optional res; ++ if (auto it = metadataJson.find(key); it != metadataJson.end()) ++ { ++ if (const std::string* value = it->get_ptr()) ++ { ++ res = *value; ++ } ++ else ++ { ++ BMCWEB_LOG_ERROR << "Incorrect reading metatadata JSON provided by " ++ "telemetry service. Missing key '" ++ << key << "'."; ++ } ++ } ++ else ++ { ++ BMCWEB_LOG_ERROR << "Incorrect reading metatadata JSON provided by " ++ "telemetry service. Key '" ++ << key << "' has a wrong type."; ++ } ++ return res; ++} ++ + inline void + getReportCollection(const std::shared_ptr& asyncResp, + const std::string& uri) +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index 7fe281d..13bf792 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -1,5 +1,6 @@ + #pragma once + ++#include "sensors.hpp" + #include "utils/telemetry_utils.hpp" + + #include +@@ -15,34 +16,56 @@ using Readings = + std::vector>; + using TimestampReadings = std::tuple; + +-inline nlohmann::json toMetricValues(const Readings& readings) ++inline bool fillMetricValues(nlohmann::json& metricValues, ++ const Readings& readings) + { +- nlohmann::json metricValues = nlohmann::json::array_t(); +- +- for (auto& [id, metadata, sensorValue, timestamp] : readings) ++ for (auto& [id, metadataStr, sensorValue, timestamp] : readings) + { ++ std::optional readingMetadataJson = ++ getMetadataJson(metadataStr); ++ if (!readingMetadataJson) ++ { ++ return false; ++ } ++ ++ std::optional sensorDbusPath = ++ readStringFromMetadata(*readingMetadataJson, "SensorDbusPath"); ++ if (!sensorDbusPath) ++ { ++ return false; ++ } ++ ++ std::optional sensorRedfishUri = ++ readStringFromMetadata(*readingMetadataJson, "SensorRedfishUri"); ++ if (!sensorRedfishUri) ++ { ++ return false; ++ } ++ ++ std::string metricDefinition = ++ std::string(metricDefinitionUri) + ++ sensors::toReadingType( ++ sdbusplus::message::object_path(*sensorDbusPath) ++ .parent_path() ++ .filename()); ++ + metricValues.push_back({ ++ {"MetricDefinition", ++ nlohmann::json{{"@odata.id", metricDefinition}}}, + {"MetricId", id}, +- {"MetricProperty", metadata}, ++ {"MetricProperty", *sensorRedfishUri}, + {"MetricValue", std::to_string(sensorValue)}, + {"Timestamp", + crow::utility::getDateTime(static_cast(timestamp))}, + }); + } + +- return metricValues; ++ return true; + } + + inline bool fillReport(nlohmann::json& json, const std::string& id, + const std::variant& var) + { +- json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; +- json["@odata.id"] = telemetry::metricReportUri + id; +- json["Id"] = id; +- json["Name"] = id; +- json["MetricReportDefinition"]["@odata.id"] = +- telemetry::metricReportDefinitionUri + id; +- + const TimestampReadings* timestampReadings = + std::get_if(&var); + if (!timestampReadings) +@@ -52,9 +75,22 @@ inline bool fillReport(nlohmann::json& json, const std::string& id, + } + + const auto& [timestamp, readings] = *timestampReadings; ++ nlohmann::json metricValues = nlohmann::json::array(); ++ if (!fillMetricValues(metricValues, readings)) ++ { ++ return false; ++ } ++ ++ json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; ++ json["@odata.id"] = telemetry::metricReportUri + id; ++ json["Id"] = id; ++ json["Name"] = id; ++ json["MetricReportDefinition"]["@odata.id"] = ++ telemetry::metricReportDefinitionUri + id; + json["Timestamp"] = + crow::utility::getDateTime(static_cast(timestamp)); +- json["MetricValues"] = toMetricValues(readings); ++ json["MetricValues"] = metricValues; ++ + return true; + } + } // namespace telemetry +diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp +index cb7ea15..44c2129 100644 +--- a/redfish-core/lib/sensors.hpp ++++ b/redfish-core/lib/sensors.hpp +@@ -21,6 +21,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + +-- +2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch deleted file mode 100644 index ffab743f6..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0ca8c383db8c9afbce63380955a20ada0acc20b7 Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -Date: Wed, 2 Jun 2021 12:44:43 +0000 -Subject: [PATCH] event service fix, added Context field to response - -Tested: - - Context field is present - - No regression detected - -Signed-off-by: Krzysztof Grobelny ---- - redfish-core/include/event_service_manager.hpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index 2b957ea..289886b 100644 ---- a/redfish-core/include/event_service_manager.hpp -+++ b/redfish-core/include/event_service_manager.hpp -@@ -556,6 +556,7 @@ class Subscription - << id; - return; - } -+ msg["Context"] = customText; - - this->sendEvent( - msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); --- -2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch new file mode 100644 index 000000000..aabe500f5 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch @@ -0,0 +1,132 @@ +From 4cf883dba6e16c56d04dbd092d30c9a13d5a5eb4 Mon Sep 17 00:00:00 2001 +From: Lukasz Kazmierczak +Date: Fri, 6 Aug 2021 15:15:17 +0200 +Subject: [PATCH] Add DELETE method for MetricReport + +Added DELETE method for removing Reports by using MetricReports uri; +metric_report.hpp and metric_report_definition.hpp files are sharing +now common lambda function for DELETE operations + +Tested on QEMU: +- Added Reports and requested from bmcweb to delete them via + /redfish/v1/TelemetryService/MetricReports/ or via + /redfish/v1/TelemetryService/MetricReportDefinitions/ +- Added two different reports via POST, deleted first of them via + MetricReports DELETE, checked by MetricReports GET if list of reports + contain only second report, deleted second report via MetricReports + DELETE and checked by MetricReports GET if list of reports is empty +- Same as one above but using MetricReportDefinitions DELETE and GET + +Signed-off-by: Lukasz Kazmierczak +Change-Id: I151bad363dcabd57246eb10b501abd24107b937e +--- + .../include/utils/telemetry_utils.hpp | 35 +++++++++++++++++++ + redfish-core/lib/metric_report.hpp | 4 +++ + redfish-core/lib/metric_report_definition.hpp | 34 +----------------- + 3 files changed, 40 insertions(+), 33 deletions(-) + +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index 5872350..743585f 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -70,5 +70,40 @@ inline std::string getDbusReportPath(const std::string& id) + return path; + } + ++inline std::function&, ++ const std::string&)> ++ getMetricReportDeleteHandler(const std::string& type) ++{ ++ return [type](const crow::Request&, ++ const std::shared_ptr& asyncResp, ++ const std::string& id) { ++ const std::string reportPath = getDbusReportPath(id); ++ ++ crow::connections::systemBus->async_method_call( ++ [asyncResp, type, id](const boost::system::error_code ec) { ++ /* ++ * boost::system::errc and std::errc are missing value ++ * for EBADR error that is defined in Linux. ++ */ ++ if (ec.value() == EBADR) ++ { ++ messages::resourceNotFound(asyncResp->res, type, id); ++ return; ++ } ++ ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ asyncResp->res.result(boost::beast::http::status::no_content); ++ }, ++ service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete"); ++ }; ++} ++ + } // namespace telemetry + } // namespace redfish +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index 63c8c19..60ce74e 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -127,5 +127,9 @@ inline void requestRoutesMetricReport(App& app) + telemetry::service, reportPath, telemetry::reportInterface, + "Update"); + }); ++ BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports//") ++ .privileges(redfish::privileges::deleteMetricReport) ++ .methods(boost::beast::http::verb::delete_)( ++ telemetry::getMetricReportDeleteHandler("MetricReports")); + } + } // namespace redfish +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index a0c4f1d..e0505e5 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -450,38 +450,6 @@ inline void requestRoutesMetricReportDefinition(App& app) + "/redfish/v1/TelemetryService/MetricReportDefinitions//") + .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) + .methods(boost::beast::http::verb::delete_)( +- [](const crow::Request&, +- const std::shared_ptr& asyncResp, +- const std::string& id) +- +- { +- const std::string reportPath = telemetry::getDbusReportPath(id); +- +- crow::connections::systemBus->async_method_call( +- [asyncResp, id](const boost::system::error_code ec) { +- /* +- * boost::system::errc and std::errc are missing value +- * for EBADR error that is defined in Linux. +- */ +- if (ec.value() == EBADR) +- { +- messages::resourceNotFound( +- asyncResp->res, "MetricReportDefinition", id); +- return; +- } +- +- if (ec) +- { +- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; +- messages::internalError(asyncResp->res); +- return; +- } +- +- asyncResp->res.result( +- boost::beast::http::status::no_content); +- }, +- telemetry::service, reportPath, +- "xyz.openbmc_project.Object.Delete", "Delete"); +- }); ++ telemetry::getMetricReportDeleteHandler("MetricReportDefinition")); + } + } // namespace redfish +-- +2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Switched-bmcweb-to-use-new-telemetry-service-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Switched-bmcweb-to-use-new-telemetry-service-API.patch deleted file mode 100644 index 4e326ff88..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Switched-bmcweb-to-use-new-telemetry-service-API.patch +++ /dev/null @@ -1,301 +0,0 @@ -From 51869fd549cd826981ad30c6cdea4c4e94a972db Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -Date: Thu, 17 Jun 2021 13:37:57 +0000 -Subject: [PATCH] Switched bmcweb to use new telemetry service API - -Added support for multiple MetricProperties. Added support for new -parameters: CollectionTimeScope, CollectionDuration. - -Tested: - - It is possible to create MetricReportDefinitions with multiple - MetricProperties. - - Stub values for new parameters are correctly passed to telemetry - service. - - All existing telemetry service functionalities remain unchanged. - -Change-Id: I2cd17069e3ea015c8f5571c29278f1d50536272a -Signed-off-by: Krzysztof Grobelny ---- - redfish-core/lib/metric_report_definition.hpp | 212 ++++++++++-------- - 1 file changed, 114 insertions(+), 98 deletions(-) - -diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp -index a0c4f1d..7c26787 100644 ---- a/redfish-core/lib/metric_report_definition.hpp -+++ b/redfish-core/lib/metric_report_definition.hpp -@@ -7,6 +7,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -17,87 +19,90 @@ namespace redfish - namespace telemetry - { - --using ReadingParameters = -- std::vector>; -+using ReadingParameters = std::vector< -+ std::tuple, std::string, -+ std::string, std::string, std::string, uint64_t>>; - - inline void fillReportDefinition( - const std::shared_ptr& asyncResp, const std::string& id, - const std::vector< -- std::pair>>& ret) -+ std::pair>>& -+ properties) - { -- asyncResp->res.jsonValue["@odata.type"] = -- "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; -- asyncResp->res.jsonValue["@odata.id"] = -- telemetry::metricReportDefinitionUri + id; -- asyncResp->res.jsonValue["Id"] = id; -- asyncResp->res.jsonValue["Name"] = id; -- asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = -- telemetry::metricReportUri + id; -- asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; -- asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; -- -- const bool* emitsReadingsUpdate = nullptr; -- const bool* logToMetricReportsCollection = nullptr; -- const ReadingParameters* readingParams = nullptr; -- const std::string* reportingType = nullptr; -- const uint64_t* interval = nullptr; -- for (const auto& [key, var] : ret) -+ try - { -- if (key == "EmitsReadingsUpdate") -+ bool emitsReadingsUpdate = false; -+ bool logToMetricReportsCollection = false; -+ ReadingParameters readingParams; -+ std::string reportingType; -+ uint64_t interval = 0u; -+ -+ sdbusplus::unpackProperties( -+ properties, "EmitsReadingsUpdate", emitsReadingsUpdate, -+ "LogToMetricReportsCollection", logToMetricReportsCollection, -+ "ReadingParametersFutureVersion", readingParams, "ReportingType", -+ reportingType, "Interval", interval); -+ -+ std::vector redfishReportActions; -+ redfishReportActions.reserve(2); -+ if (emitsReadingsUpdate) - { -- emitsReadingsUpdate = std::get_if(&var); -+ redfishReportActions.emplace_back("RedfishEvent"); - } -- else if (key == "LogToMetricReportsCollection") -+ if (logToMetricReportsCollection) - { -- logToMetricReportsCollection = std::get_if(&var); -+ redfishReportActions.emplace_back("LogToMetricReportsCollection"); - } -- else if (key == "ReadingParameters") -- { -- readingParams = std::get_if(&var); -- } -- else if (key == "ReportingType") -- { -- reportingType = std::get_if(&var); -- } -- else if (key == "Interval") -+ -+ nlohmann::json metrics = nlohmann::json::array(); -+ for (auto& [sensorPath, operationType, id, metadata, -+ collectionTimeScope, collectionDuration] : readingParams) - { -- interval = std::get_if(&var); -+ std::vector metricProperties; -+ -+ nlohmann::json parsedMetadata = nlohmann::json::parse(metadata); -+ if (!json_util::readJson(parsedMetadata, asyncResp->res, -+ "MetricProperties", metricProperties)) -+ { -+ BMCWEB_LOG_ERROR << "Failed to read metadata"; -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ -+ metrics.push_back({ -+ {"MetricId", id}, -+ {"MetricProperties", std::move(metricProperties)}, -+ }); - } -- } -- if (!emitsReadingsUpdate || !logToMetricReportsCollection || -- !readingParams || !reportingType || !interval) -- { -- BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; -- messages::internalError(asyncResp->res); -- return; -- } - -- std::vector redfishReportActions; -- redfishReportActions.reserve(2); -- if (*emitsReadingsUpdate) -- { -- redfishReportActions.emplace_back("RedfishEvent"); -+ asyncResp->res.jsonValue["@odata.type"] = -+ "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; -+ asyncResp->res.jsonValue["@odata.id"] = -+ telemetry::metricReportDefinitionUri + id; -+ asyncResp->res.jsonValue["Id"] = id; -+ asyncResp->res.jsonValue["Name"] = id; -+ asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = -+ telemetry::metricReportUri + id; -+ asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; -+ asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; -+ asyncResp->res.jsonValue["Metrics"] = metrics; -+ asyncResp->res.jsonValue["MetricReportDefinitionType"] = reportingType; -+ asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; -+ asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = -+ time_utils::toDurationString(std::chrono::milliseconds(interval)); - } -- if (*logToMetricReportsCollection) -+ catch (const sdbusplus::exception::UnpackPropertyError& error) - { -- redfishReportActions.emplace_back("LogToMetricReportsCollection"); -+ BMCWEB_LOG_ERROR << error.what() << ", property: " -+ << error.propertyName + ", reason: " << error.reason; -+ messages::internalError(asyncResp->res); - } -- -- nlohmann::json metrics = nlohmann::json::array(); -- for (auto& [sensorPath, operationType, id, metadata] : *readingParams) -+ catch (const nlohmann::json::parse_error& e) - { -- metrics.push_back({ -- {"MetricId", id}, -- {"MetricProperties", {metadata}}, -- }); -+ BMCWEB_LOG_ERROR << "Failed to parse metadata: " << e.what(); -+ messages::internalError(asyncResp->res); - } -- asyncResp->res.jsonValue["Metrics"] = metrics; -- asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; -- asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; -- asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = -- time_utils::toDurationString(std::chrono::milliseconds(*interval)); - } - - struct AddReportArgs -@@ -275,6 +280,11 @@ class AddReport - - for (const auto& [id, uris] : args.metrics) - { -+ std::vector dbusPaths; -+ dbusPaths.reserve(uris.size()); -+ nlohmann::json metadata; -+ metadata["MetricProperties"] = nlohmann::json::array(); -+ - for (size_t i = 0; i < uris.size(); i++) - { - const std::string& uri = uris[i]; -@@ -291,8 +301,12 @@ class AddReport - } - - const std::string& dbusPath = el->second; -- readingParams.emplace_back(dbusPath, "SINGLE", id, uri); -+ dbusPaths.emplace_back(dbusPath); -+ metadata["MetricProperties"].emplace_back(uri); - } -+ -+ readingParams.emplace_back(dbusPaths, "SINGLE", id, metadata.dump(), -+ "Point", 0u); - } - const std::shared_ptr aResp = asyncResp; - crow::connections::systemBus->async_method_call( -@@ -330,10 +344,10 @@ class AddReport - messages::created(aResp->res); - }, - telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", -- "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", -- "TelemetryService/" + args.name, args.reportingType, -- args.emitsReadingsUpdate, args.logToMetricReportsCollection, -- args.interval, readingParams); -+ "xyz.openbmc_project.Telemetry.ReportManager", -+ "AddReportFutureVersion", "TelemetryService/" + args.name, -+ args.reportingType, args.emitsReadingsUpdate, -+ args.logToMetricReportsCollection, args.interval, readingParams); - } - - void insert(const boost::container::flat_map& el) -@@ -415,37 +429,39 @@ inline void requestRoutesMetricReportDefinition(App& app) - BMCWEB_ROUTE(app, - "/redfish/v1/TelemetryService/MetricReportDefinitions//") - .privileges(redfish::privileges::getMetricReportDefinition) -- .methods(boost::beast::http::verb::get)( -- [](const crow::Request&, -- const std::shared_ptr& asyncResp, -- const std::string& id) { -- crow::connections::systemBus->async_method_call( -- [asyncResp, id]( -- const boost::system::error_code ec, -- const std::vector>>& ret) { -- if (ec.value() == EBADR || -- ec == boost::system::errc::host_unreachable) -- { -- messages::resourceNotFound( -- asyncResp->res, "MetricReportDefinition", id); -- return; -- } -- if (ec) -- { -- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; -- messages::internalError(asyncResp->res); -- return; -- } -+ .methods( -+ boost::beast::http::verb::get)([](const crow::Request&, -+ const std::shared_ptr< -+ bmcweb::AsyncResp>& asyncResp, -+ const std::string& id) { -+ sdbusplus::asio::getAllProperties( -+ *crow::connections::systemBus, telemetry::service, -+ telemetry::getDbusReportPath(id), telemetry::reportInterface, -+ [asyncResp, -+ id](boost::system::error_code ec, -+ const std::vector>>& -+ properties) { -+ if (ec.value() == EBADR || -+ ec == boost::system::errc::host_unreachable) -+ { -+ messages::resourceNotFound( -+ asyncResp->res, "MetricReportDefinition", id); -+ return; -+ } -+ if (ec) -+ { -+ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ -+ telemetry::fillReportDefinition(asyncResp, id, properties); -+ }); -+ }); - -- telemetry::fillReportDefinition(asyncResp, id, ret); -- }, -- telemetry::service, telemetry::getDbusReportPath(id), -- "org.freedesktop.DBus.Properties", "GetAll", -- telemetry::reportInterface); -- }); - BMCWEB_ROUTE(app, - "/redfish/v1/TelemetryService/MetricReportDefinitions//") - .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) --- -2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch new file mode 100644 index 000000000..0646aba5c --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch @@ -0,0 +1,313 @@ +From a1e89d356ba5ed594a1494efe8257946e1062396 Mon Sep 17 00:00:00 2001 +From: Lukasz Kazmierczak +Date: Tue, 31 Aug 2021 14:35:31 +0200 +Subject: [PATCH] Add GET method for TriggerCollection + +Added GET method for retrieving list of Triggers from Telemetry service + +Tested: +- Added single Trigger and requested result from bmcweb via + /redfish/v1/TelemetryService/Triggers +- Added multiple Triggers numeric and discrete, and requested results + from bmcweb via /redfish/v1/TelemetryService/Triggers +- Verified uri /redfish/v1/TelemetryService/Triggers by using + Redfish-Service-Validator (all passed) + +Signed-off-by: Lukasz Kazmierczak +Change-Id: Ide00eb44901ea1b97b80fc5c5ddfd97e393d4a04 +--- + redfish-core/include/redfish.hpp | 2 + + .../include/utils/telemetry_utils.hpp | 40 ++++++++--- + redfish-core/lib/metric_report.hpp | 6 +- + redfish-core/lib/metric_report_definition.hpp | 6 +- + redfish-core/lib/trigger.hpp | 31 ++++++++ + scripts/update_schemas.py | 1 + + static/redfish/v1/$metadata/index.xml | 3 + + .../v1/schema/TriggersCollection_v1.xml | 70 +++++++++++++++++++ + 8 files changed, 144 insertions(+), 15 deletions(-) + create mode 100644 redfish-core/lib/trigger.hpp + create mode 100644 static/redfish/v1/schema/TriggersCollection_v1.xml + +diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp +index 9fb0ffe..99b3fe6 100644 +--- a/redfish-core/include/redfish.hpp ++++ b/redfish-core/include/redfish.hpp +@@ -42,6 +42,7 @@ + #include "../lib/task.hpp" + #include "../lib/telemetry_service.hpp" + #include "../lib/thermal.hpp" ++#include "../lib/trigger.hpp" + #include "../lib/update_service.hpp" + #include "../lib/virtual_media.hpp" + +@@ -197,6 +198,7 @@ class RedfishService + + hypervisor::requestRoutesHypervisorSystems(app); + ++ requestRoutesTriggerCollection(app); + requestRoutesTelemetryService(app); + requestRoutesMetricReportDefinitionCollection(app); + requestRoutesMetricReportDefinition(app); +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index c0c5ba3..df1aa68 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -9,6 +9,8 @@ namespace telemetry + { + + constexpr const char* service = "xyz.openbmc_project.Telemetry"; ++constexpr const char* reportSubtree = ++ "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"; + constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; + constexpr const char* metricDefinitionUri = + "/redfish/v1/TelemetryService/MetricDefinitions/"; +@@ -16,6 +18,11 @@ constexpr const char* metricReportDefinitionUri = + "/redfish/v1/TelemetryService/MetricReportDefinitions/"; + constexpr const char* metricReportUri = + "/redfish/v1/TelemetryService/MetricReports/"; ++constexpr const char* triggerSubtree = ++ "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"; ++constexpr const char* triggerInterface = ++ "xyz.openbmc_project.Telemetry.Trigger"; ++constexpr const char* triggerUri = "/redfish/v1/TelemetryService/Triggers/"; + + inline std::optional + getMetadataJson(const std::string& metadataStr) +@@ -57,15 +64,27 @@ inline std::optional + return res; + } + +-inline void +- getReportCollection(const std::shared_ptr& asyncResp, +- const std::string& uri) ++struct CollectionParams + { +- const std::array interfaces = {reportInterface}; ++ const char* subtree; ++ int depth; ++ std::array interfaces; + ++ CollectionParams() = delete; ++ CollectionParams(const char* st, int dp, ++ const std::array& ifaces) : ++ subtree{st}, ++ depth{dp}, interfaces{ifaces} ++ {} ++}; ++ ++inline void getCollection(const std::shared_ptr& asyncResp, ++ const std::string& uri, ++ const CollectionParams& params) ++{ + crow::connections::systemBus->async_method_call( + [asyncResp, uri](const boost::system::error_code ec, +- const std::vector& reports) { ++ const std::vector& items) { + if (ec == boost::system::errc::io_error) + { + asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); +@@ -82,13 +101,13 @@ inline void + nlohmann::json& members = asyncResp->res.jsonValue["Members"]; + members = nlohmann::json::array(); + +- for (const std::string& report : reports) ++ for (const std::string& item : items) + { +- sdbusplus::message::object_path path(report); ++ sdbusplus::message::object_path path(item); + std::string name = path.filename(); + if (name.empty()) + { +- BMCWEB_LOG_ERROR << "Received invalid path: " << report; ++ BMCWEB_LOG_ERROR << "Received invalid path: " << item; + messages::internalError(asyncResp->res); + return; + } +@@ -99,9 +118,8 @@ inline void + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", +- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", +- "/xyz/openbmc_project/Telemetry/Reports/TelemetryService", 1, +- interfaces); ++ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", params.subtree, ++ params.depth, params.interfaces); + } + + inline std::string getDbusReportPath(const std::string& id) +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index 13bf792..ea4cd62 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -108,8 +108,10 @@ inline void requestRoutesMetricReportCollection(App& app) + "/redfish/v1/TelemetryService/MetricReports"; + asyncResp->res.jsonValue["Name"] = "Metric Report Collection"; + +- telemetry::getReportCollection(asyncResp, +- telemetry::metricReportUri); ++ telemetry::getCollection( ++ asyncResp, telemetry::metricReportUri, ++ telemetry::CollectionParams(telemetry::reportSubtree, 1, ++ {telemetry::reportInterface})); + }); + } + +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index 7c26787..c97a1df 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -377,8 +377,10 @@ inline void requestRoutesMetricReportDefinitionCollection(App& app) + asyncResp->res.jsonValue["Name"] = + "Metric Definition Collection"; + +- telemetry::getReportCollection( +- asyncResp, telemetry::metricReportDefinitionUri); ++ telemetry::getCollection( ++ asyncResp, telemetry::metricReportDefinitionUri, ++ telemetry::CollectionParams(telemetry::reportSubtree, 1, ++ {telemetry::reportInterface})); + }); + + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") +diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp +new file mode 100644 +index 0000000..681b3b4 +--- /dev/null ++++ b/redfish-core/lib/trigger.hpp +@@ -0,0 +1,31 @@ ++#pragma once ++ ++#include "utils/telemetry_utils.hpp" ++ ++#include ++#include ++ ++namespace redfish ++{ ++ ++inline void requestRoutesTriggerCollection(App& app) ++{ ++ BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") ++ .privileges(redfish::privileges::getTriggersCollection) ++ .methods(boost::beast::http::verb::get)( ++ [](const crow::Request&, ++ const std::shared_ptr& asyncResp) { ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#TriggersCollection.TriggersCollection"; ++ asyncResp->res.jsonValue["@odata.id"] = ++ "/redfish/v1/TelemetryService/Triggers"; ++ asyncResp->res.jsonValue["Name"] = "Triggers Collection"; ++ ++ telemetry::getCollection( ++ asyncResp, telemetry::triggerUri, ++ telemetry::CollectionParams(telemetry::triggerSubtree, 1, ++ {telemetry::triggerInterface})); ++ }); ++} ++ ++} // namespace redfish +diff --git a/scripts/update_schemas.py b/scripts/update_schemas.py +index dd39278..d66a59a 100755 +--- a/scripts/update_schemas.py ++++ b/scripts/update_schemas.py +@@ -93,6 +93,7 @@ include_list = [ + 'TaskService', + 'TelemetryService', + 'Thermal', ++ 'TriggersCollection', + 'UpdateService', + 'VLanNetworkInterfaceCollection', + 'VLanNetworkInterface', +diff --git a/static/redfish/v1/$metadata/index.xml b/static/redfish/v1/$metadata/index.xml +index 876ebfb..75e3dd4 100644 +--- a/static/redfish/v1/$metadata/index.xml ++++ b/static/redfish/v1/$metadata/index.xml +@@ -2215,6 +2215,9 @@ + + + ++ ++ ++ + + + +diff --git a/static/redfish/v1/schema/TriggersCollection_v1.xml b/static/redfish/v1/schema/TriggersCollection_v1.xml +new file mode 100644 +index 0000000..399bebd +--- /dev/null ++++ b/static/redfish/v1/schema/TriggersCollection_v1.xml +@@ -0,0 +1,70 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ /redfish/v1/TelemetryService/Triggers ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch deleted file mode 100644 index d3a7c0a35..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch +++ /dev/null @@ -1,268 +0,0 @@ -From d37ba16f837380ea5fbd7fae2d0f2e229c601754 Mon Sep 17 00:00:00 2001 -From: Szymon Dompke -Date: Mon, 28 Jun 2021 11:10:23 +0200 -Subject: [PATCH] Add support for MetricDefinition property in MetricReport - -Added MetricDefinition as part of MetricValues array returned by -MetricReport. It contains single @odata.id with URI to proper -MetricDefinition resource - depending on MetricProperty. - -Testing done: -- GET request on redfish/v1/TelemetryService/MetricReports - got response with MetricDefinition and proper id inside - MetricValues array. - -Testing steps: -1. POST on redfish/v1/TelemetryService/MetricReportDefinitions - with body: -{ - "Id": "PeriodicReport_1", - "MetricReportDefinitionType": "Periodic", - "ReportActions": [ - "LogToMetricReportsCollection", - "RedfishEvent" - ], - "Metrics": [ - { - "MetricId": "sensor_1", - "MetricProperties": [ - "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading" - ] - } - ], - "Schedule": { - "RecurrenceInterval": "PT10S" - } -} - -2. GET on redfish/v1/TelemetryService/MetricReports/PeriodicReport_1 - should return: -{ - "@odata.id": - "/redfish/v1/TelemetryService/MetricReports/PeriodicReport_1", - "@odata.type": "#MetricReport.v1_3_0.MetricReport", - "Id": "PeriodicReport_1", - "MetricReportDefinition": { - "@odata.id": - "/redfish/v1/TelemetryService/MetricReportDefinitions/PeriodicReport_1" - }, - "MetricValues": [ - { - "MetricDefinition": { - "@odata.id": - "/redfish/v1/TelemetryService/MetricDefinitions/Rotational" - }, - "MetricId": "sensor_1", - "MetricProperty": - "/redfish/v1/Chassis/AC_Baseboard/Thermal#/Fans/1/Reading", - "MetricValue": "nan", - "Timestamp": "1970-01-01T00:03:21+00:00" - } - ], - "Name": "PeriodicReport_1", - "Timestamp": "1970-01-01T00:03:21+00:00" -} - -Change-Id: I7181c612f9b443015d551259bae25303aa436822 -Signed-off-by: Szymon Dompke ---- - meson.build | 4 +- - .../include/utils/telemetry_utils.hpp | 40 ++++++++++++ - redfish-core/lib/metric_report.hpp | 64 +++++++++++++++---- - redfish-core/lib/sensors.hpp | 2 + - 4 files changed, 95 insertions(+), 15 deletions(-) - -diff --git a/meson.build b/meson.build -index bdc514b..aadfd7d 100644 ---- a/meson.build -+++ b/meson.build -@@ -354,6 +354,8 @@ srcfiles_unittest = ['include/ut/dbus_utility_test.cpp', - 'redfish-core/ut/time_utils_test.cpp', - 'http/ut/utility_test.cpp'] - -+srcfiles_unittest_dependencies = ['redfish-core/src/error_messages.cpp'] -+ - # Gather the Configuration data - - conf_data = configuration_data() -@@ -411,7 +413,7 @@ executable('bmcweb',srcfiles_bmcweb, - if(get_option('tests').enabled()) - foreach src_test : srcfiles_unittest - testname = src_test.split('/')[-1].split('.')[0] -- test(testname,executable(testname,src_test, -+ test(testname,executable(testname,[src_test] + srcfiles_unittest_dependencies, - include_directories : incdir, - install_dir: bindir, - dependencies: [ -diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp -index 1b4f75d..c0c5ba3 100644 ---- a/redfish-core/include/utils/telemetry_utils.hpp -+++ b/redfish-core/include/utils/telemetry_utils.hpp -@@ -17,6 +17,46 @@ constexpr const char* metricReportDefinitionUri = - constexpr const char* metricReportUri = - "/redfish/v1/TelemetryService/MetricReports/"; - -+inline std::optional -+ getMetadataJson(const std::string& metadataStr) -+{ -+ std::optional res = -+ nlohmann::json::parse(metadataStr, nullptr, false); -+ if (res->is_discarded()) -+ { -+ BMCWEB_LOG_ERROR << "Malformed reading metatadata JSON provided by " -+ "telemetry service."; -+ return std::nullopt; -+ } -+ return res; -+} -+ -+inline std::optional -+ readStringFromMetadata(const nlohmann::json& metadataJson, const char* key) -+{ -+ std::optional res; -+ if (auto it = metadataJson.find(key); it != metadataJson.end()) -+ { -+ if (const std::string* value = it->get_ptr()) -+ { -+ res = *value; -+ } -+ else -+ { -+ BMCWEB_LOG_ERROR << "Incorrect reading metatadata JSON provided by " -+ "telemetry service. Missing key '" -+ << key << "'."; -+ } -+ } -+ else -+ { -+ BMCWEB_LOG_ERROR << "Incorrect reading metatadata JSON provided by " -+ "telemetry service. Key '" -+ << key << "' has a wrong type."; -+ } -+ return res; -+} -+ - inline void - getReportCollection(const std::shared_ptr& asyncResp, - const std::string& uri) -diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp -index 7fe281d..13bf792 100644 ---- a/redfish-core/lib/metric_report.hpp -+++ b/redfish-core/lib/metric_report.hpp -@@ -1,5 +1,6 @@ - #pragma once - -+#include "sensors.hpp" - #include "utils/telemetry_utils.hpp" - - #include -@@ -15,34 +16,56 @@ using Readings = - std::vector>; - using TimestampReadings = std::tuple; - --inline nlohmann::json toMetricValues(const Readings& readings) -+inline bool fillMetricValues(nlohmann::json& metricValues, -+ const Readings& readings) - { -- nlohmann::json metricValues = nlohmann::json::array_t(); -- -- for (auto& [id, metadata, sensorValue, timestamp] : readings) -+ for (auto& [id, metadataStr, sensorValue, timestamp] : readings) - { -+ std::optional readingMetadataJson = -+ getMetadataJson(metadataStr); -+ if (!readingMetadataJson) -+ { -+ return false; -+ } -+ -+ std::optional sensorDbusPath = -+ readStringFromMetadata(*readingMetadataJson, "SensorDbusPath"); -+ if (!sensorDbusPath) -+ { -+ return false; -+ } -+ -+ std::optional sensorRedfishUri = -+ readStringFromMetadata(*readingMetadataJson, "SensorRedfishUri"); -+ if (!sensorRedfishUri) -+ { -+ return false; -+ } -+ -+ std::string metricDefinition = -+ std::string(metricDefinitionUri) + -+ sensors::toReadingType( -+ sdbusplus::message::object_path(*sensorDbusPath) -+ .parent_path() -+ .filename()); -+ - metricValues.push_back({ -+ {"MetricDefinition", -+ nlohmann::json{{"@odata.id", metricDefinition}}}, - {"MetricId", id}, -- {"MetricProperty", metadata}, -+ {"MetricProperty", *sensorRedfishUri}, - {"MetricValue", std::to_string(sensorValue)}, - {"Timestamp", - crow::utility::getDateTime(static_cast(timestamp))}, - }); - } - -- return metricValues; -+ return true; - } - - inline bool fillReport(nlohmann::json& json, const std::string& id, - const std::variant& var) - { -- json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; -- json["@odata.id"] = telemetry::metricReportUri + id; -- json["Id"] = id; -- json["Name"] = id; -- json["MetricReportDefinition"]["@odata.id"] = -- telemetry::metricReportDefinitionUri + id; -- - const TimestampReadings* timestampReadings = - std::get_if(&var); - if (!timestampReadings) -@@ -52,9 +75,22 @@ inline bool fillReport(nlohmann::json& json, const std::string& id, - } - - const auto& [timestamp, readings] = *timestampReadings; -+ nlohmann::json metricValues = nlohmann::json::array(); -+ if (!fillMetricValues(metricValues, readings)) -+ { -+ return false; -+ } -+ -+ json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; -+ json["@odata.id"] = telemetry::metricReportUri + id; -+ json["Id"] = id; -+ json["Name"] = id; -+ json["MetricReportDefinition"]["@odata.id"] = -+ telemetry::metricReportDefinitionUri + id; - json["Timestamp"] = - crow::utility::getDateTime(static_cast(timestamp)); -- json["MetricValues"] = toMetricValues(readings); -+ json["MetricValues"] = metricValues; -+ - return true; - } - } // namespace telemetry -diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp -index bccbb94..3e1d003 100644 ---- a/redfish-core/lib/sensors.hpp -+++ b/redfish-core/lib/sensors.hpp -@@ -21,6 +21,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - --- -2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch deleted file mode 100644 index 1cdd59d4b..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 872a7bdb9c272944914d7c5babc751e6bb33afec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Adrian=20Ambro=C5=BCewicz?= -Date: Tue, 3 Aug 2021 13:59:31 +0200 -Subject: [PATCH] Generalize ReadingType in MetricDefinition - -Recent addition of PMT required adding new type of sensor 'count', which -doesnt comply with any of Redfish-defined Sensor.ReadingType values. - -To support property of this kind MetricDefinition implementation was -altered to support sensor types not covered by Redfish types by -a 'fallback' to direct usage of sensor type. Populating 'Units' was also -modified, so it won't be shown if value does not have any units mapped. - -Testing: -- PMT counters are shown properly in MetricDefinitions/Count -- Redfish Validator passes ---- - redfish-core/lib/metric_definition.hpp | 63 ++++++++++++++++---------- - 1 file changed, 39 insertions(+), 24 deletions(-) - -diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp -index 2443996..fcab44d 100644 ---- a/redfish-core/lib/metric_definition.hpp -+++ b/redfish-core/lib/metric_definition.hpp -@@ -11,6 +11,18 @@ namespace redfish - namespace telemetry - { - -+std::string groupName(const std::string& sensorType) -+{ -+ std::string group = sensors::toReadingType(sensorType); -+ if (group.empty()) -+ { -+ // Fallback for types not covered by standard Redfish Sensor.ReadingType -+ group = sensorType; -+ group[0] = static_cast(std::toupper(group[0])); -+ } -+ return group; -+} -+ - void addMembers(crow::Response& res, - const boost::container::flat_map& el) - { -@@ -30,8 +42,7 @@ void addMembers(crow::Response& res, - nlohmann::json& members = res.jsonValue["Members"]; - - const std::string odataId = -- std::string(telemetry::metricDefinitionUri) + -- sensors::toReadingType(type); -+ std::string(telemetry::metricDefinitionUri) + groupName(type); - - const auto it = std::find_if(members.begin(), members.end(), - [&odataId](const nlohmann::json& item) { -@@ -125,15 +136,15 @@ inline void requestRoutesMetricDefinitionCollection(App& app) - namespace telemetry - { - --bool isSensorIdSupported(std::string_view readingType) -+bool isSensorIdSupported(std::string_view group) - { - for (const std::pair>& - typeToPaths : sensors::dbus::paths) - { - for (const char* supportedPath : typeToPaths.second) - { -- if (readingType == -- sensors::toReadingType( -+ if (group == -+ groupName( - sdbusplus::message::object_path(supportedPath).filename())) - { - return true; -@@ -144,7 +155,7 @@ bool isSensorIdSupported(std::string_view readingType) - } - - void addMetricProperty( -- bmcweb::AsyncResp& asyncResp, const std::string& readingType, -+ bmcweb::AsyncResp& asyncResp, const std::string& group, - const boost::container::flat_map& el) - { - nlohmann::json& metricProperties = -@@ -155,7 +166,7 @@ void addMetricProperty( - std::string sensorId; - if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) - { -- if (sensors::toReadingType(sensorId) == readingType) -+ if (groupName(sensorId) == group) - { - metricProperties.push_back(redfishSensor); - } -@@ -172,33 +183,37 @@ inline void requestRoutesMetricDefinition(App& app) - .methods(boost::beast::http::verb::get)( - [](const crow::Request&, - const std::shared_ptr& asyncResp, -- const std::string& readingType) { -- if (!telemetry::isSensorIdSupported(readingType)) -+ const std::string& group) { -+ if (!telemetry::isSensorIdSupported(group)) - { - messages::resourceNotFound(asyncResp->res, -- "MetricDefinition", readingType); -+ "MetricDefinition", group); - return; - } - - asyncResp->res.jsonValue["MetricProperties"] = - nlohmann::json::array(); -- asyncResp->res.jsonValue["Id"] = readingType; -- asyncResp->res.jsonValue["Name"] = readingType; -+ asyncResp->res.jsonValue["Id"] = group; -+ asyncResp->res.jsonValue["Name"] = group; - asyncResp->res.jsonValue["@odata.id"] = -- telemetry::metricDefinitionUri + readingType; -+ telemetry::metricDefinitionUri + group; - asyncResp->res.jsonValue["@odata.type"] = - "#MetricDefinition.v1_0_3.MetricDefinition"; - asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; - asyncResp->res.jsonValue["MetricType"] = "Numeric"; - asyncResp->res.jsonValue["IsLinear"] = true; - asyncResp->res.jsonValue["Implementation"] = "PhysicalSensor"; -- asyncResp->res.jsonValue["Units"] = -- sensors::toReadingUnits(readingType); -+ -+ std::string readingUnits = sensors::toReadingUnits(group); -+ if (!readingUnits.empty()) -+ { -+ asyncResp->res.jsonValue["Units"] = readingUnits; -+ } - - utils::getChassisNames( -- [asyncResp, readingType]( -- boost::system::error_code ec, -- const std::vector& chassisNames) { -+ [asyncResp, -+ group](boost::system::error_code ec, -+ const std::vector& chassisNames) { - if (ec) - { - messages::internalError(asyncResp->res); -@@ -208,10 +223,10 @@ inline void requestRoutesMetricDefinition(App& app) - } - - auto handleRetrieveUriToDbusMap = -- [asyncResp, readingType]( -- const boost::beast::http::status status, -- const boost::container::flat_map< -- std::string, std::string>& uriToDbus) { -+ [asyncResp, -+ group](const boost::beast::http::status status, -+ const boost::container::flat_map< -+ std::string, std::string>& uriToDbus) { - if (status != boost::beast::http::status::ok) - { - BMCWEB_LOG_ERROR -@@ -221,8 +236,8 @@ inline void requestRoutesMetricDefinition(App& app) - messages::internalError(asyncResp->res); - return; - } -- telemetry::addMetricProperty( -- *asyncResp, readingType, uriToDbus); -+ telemetry::addMetricProperty(*asyncResp, group, -+ uriToDbus); - }; - - for (const std::string& chassisName : chassisNames) --- -2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch new file mode 100644 index 000000000..987a43b4c --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch @@ -0,0 +1,26 @@ +From 472ac5f15a19917042852b243e8b668b3ab49e32 Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Tue, 22 Jun 2021 13:59:48 +0000 +Subject: [PATCH] Revert "Remove LogService from TelemetryService" + +This reverts commit 2b3da45876aac57a36d3093379a992d699e7e396. +--- + redfish-core/lib/telemetry_service.hpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp +index 37221c3..f3a1efb 100644 +--- a/redfish-core/lib/telemetry_service.hpp ++++ b/redfish-core/lib/telemetry_service.hpp +@@ -30,6 +30,8 @@ inline void requestRoutesTelemetryService(App& app) + "/redfish/v1/TelemetryService/MetricReports"; + asyncResp->res.jsonValue["MetricDefinitions"]["@odata.id"] = + "/redfish/v1/TelemetryService/MetricDefinitions"; ++ asyncResp->res.jsonValue["LogService"]["@odata.id"] = ++ "/redfish/v1/Managers/bmc/LogServices/Journal"; + + crow::connections::systemBus->async_method_call( + [asyncResp]( +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch new file mode 100644 index 000000000..ffab743f6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch @@ -0,0 +1,29 @@ +From 0ca8c383db8c9afbce63380955a20ada0acc20b7 Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Wed, 2 Jun 2021 12:44:43 +0000 +Subject: [PATCH] event service fix, added Context field to response + +Tested: + - Context field is present + - No regression detected + +Signed-off-by: Krzysztof Grobelny +--- + redfish-core/include/event_service_manager.hpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp +index 2b957ea..289886b 100644 +--- a/redfish-core/include/event_service_manager.hpp ++++ b/redfish-core/include/event_service_manager.hpp +@@ -556,6 +556,7 @@ class Subscription + << id; + return; + } ++ msg["Context"] = customText; + + this->sendEvent( + msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch new file mode 100644 index 000000000..bd6e64346 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch @@ -0,0 +1,93 @@ +From d9baec3ccdff5ed4d1620f374a252c769de5b45b Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Thu, 19 Aug 2021 10:55:38 +0000 +Subject: [PATCH] Generalize ReadingType in MetricDefinition + +Recent addition of PMT required adding new type of sensor 'count', which +doesnt comply with any of Redfish-defined Sensor.ReadingType values. + +To support property of this kind MetricDefinition implementation was +altered to support sensor types not covered by Redfish types by +a 'fallback' to direct usage of sensor type. Populating 'Units' was also +modified, so it won't be shown if value does not have any units mapped. + +Testing: +- PMT counters are shown properly in MetricDefinitions/Count +- Redfish Validator passes +--- + redfish-core/lib/metric_definition.hpp | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp +index 019168b..df29b65 100644 +--- a/redfish-core/lib/metric_definition.hpp ++++ b/redfish-core/lib/metric_definition.hpp +@@ -33,6 +33,18 @@ bool containsOdata(const nlohmann::json& json, const std::string& odataId) + return it != json.end(); + } + ++std::string groupName(const std::string& sensorType) ++{ ++ std::string group = sensors::toReadingType(sensorType); ++ if (group.empty()) ++ { ++ // Fallback for types not covered by standard Redfish Sensor.ReadingType ++ group = sensorType; ++ group[0] = static_cast(std::toupper(group[0])); ++ } ++ return group; ++} ++ + void addMembers(crow::Response& res, + const boost::container::flat_map& el) + { +@@ -52,8 +64,7 @@ void addMembers(crow::Response& res, + nlohmann::json& members = res.jsonValue["Members"]; + + const std::string odataId = +- std::string(telemetry::metricDefinitionUri) + +- sensors::toReadingType(type); ++ std::string(telemetry::metricDefinitionUri) + groupName(type); + + if (!containsOdata(members, odataId)) + { +@@ -149,15 +160,15 @@ inline void requestRoutesMetricDefinitionCollection(App& app) + namespace telemetry + { + +-bool isSensorIdSupported(std::string_view readingType) ++bool isSensorIdSupported(std::string_view group) + { + for (const std::pair>& + typeToPaths : sensors::dbus::paths) + { + for (const char* supportedPath : typeToPaths.second) + { +- if (readingType == +- sensors::toReadingType( ++ if (group == ++ groupName( + sdbusplus::message::object_path(supportedPath).filename())) + { + return true; +@@ -168,7 +179,7 @@ bool isSensorIdSupported(std::string_view readingType) + } + + void addMetricProperty( +- bmcweb::AsyncResp& asyncResp, const std::string& readingType, ++ bmcweb::AsyncResp& asyncResp, const std::string& group, + const boost::container::flat_map& el) + { + nlohmann::json& metricProperties = +@@ -179,7 +190,7 @@ void addMetricProperty( + std::string sensorId; + if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) + { +- if (sensors::toReadingType(sensorId) == readingType) ++ if (groupName(sensorId) == group) + { + metricProperties.push_back(redfishSensor); + } +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README index cd15a815c..8dab07e2b 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README @@ -3,22 +3,28 @@ Until change is integrated they will be manually merged here to enable feature i Current revisions: - Add support for MetricDefinition scheme - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/33363/89 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/33363/93 - Sync Telmetry service with EventService - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/36 - -- LogService field, actual implementation will be upstreamed with triggers feature - file://telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch - -- Event service fix for Context field - file://telemetry/0004-event-service-fix-added-Context-field-to-response.patch + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/40 - Switched bmcweb to use new telemetry service API - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44270/4 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44270/5 - Add support for MetricDefinition property in MetricReport - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44512/8 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44512/9 + +- Add DELETE method for MetricReport + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/45688/5 + +- Add GET method for TriggerCollection + file://telemetry/0006-Add-GET-method-for-TriggerCollection.patch + +- LogService field, actual implementation will be upstreamed with triggers feature + file://telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch + +- Event service fix for Context field + file://telemetry/0008-event-service-fix-added-Context-field-to-response.patch - Generalize ReadingType in MetricDefinition - file://telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch \ No newline at end of file + file://telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0004-Invalid-status-code-from-InsertMedia-REST-methods.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0004-Invalid-status-code-from-InsertMedia-REST-methods.patch index b29082dce..439b05b3c 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0004-Invalid-status-code-from-InsertMedia-REST-methods.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0004-Invalid-status-code-from-InsertMedia-REST-methods.patch @@ -1,4 +1,4 @@ -From 95f7ca477a8353fa7b99f463de9ee310dda13735 Mon Sep 17 00:00:00 2001 +From 437a2a854303ed4e05344684b1990806464268cd Mon Sep 17 00:00:00 2001 From: Krzysztof Grobelny Date: Thu, 1 Jul 2021 10:08:27 +0000 Subject: [PATCH] Invalid status code from InsertMedia REST methods GET, PUT, @@ -10,15 +10,16 @@ Not allowed for Legacy and Not found for Proxy. Change-Id: Ib4c0a3e9a2a8853caa74c59239d9fcfed99c5e8b Signed-off-by: Alicja Rybak +Signed-off-by: P Dheeraj Srujan Kumar --- - redfish-core/lib/virtual_media.hpp | 129 +++++++++++++++++++++++++++++ - 1 file changed, 129 insertions(+) + redfish-core/lib/virtual_media.hpp | 137 +++++++++++++++++++++++++++++ + 1 file changed, 137 insertions(+) diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp -index a834c69..186c04b 100644 +index 3b9f7ef..7d77b9f 100644 --- a/redfish-core/lib/virtual_media.hpp +++ b/redfish-core/lib/virtual_media.hpp -@@ -28,6 +28,109 @@ +@@ -30,6 +30,117 @@ namespace redfish { @@ -50,6 +51,14 @@ index a834c69..186c04b 100644 + + return; + } ++ ++ if (getObjectType.size() == 0) ++ { ++ BMCWEB_LOG_ERROR << "ObjectMapper : No Service found"; ++ aResp->res.result(boost::beast::http::status::not_found); ++ return; ++ } ++ + std::string service = getObjectType.begin()->first; + BMCWEB_LOG_DEBUG << "GetObjectType: " << service; + @@ -128,7 +137,7 @@ index a834c69..186c04b 100644 /** * @brief Function extracts transfer protocol name from URI. */ -@@ -829,6 +932,32 @@ inline void doVmAction(const std::shared_ptr& asyncResp, +@@ -844,6 +955,32 @@ inline void doVmAction(const std::shared_ptr& asyncResp, inline void requestNBDVirtualMediaRoutes(App& app) { @@ -160,7 +169,7 @@ index a834c69..186c04b 100644 + BMCWEB_ROUTE(app, "/redfish/v1/Managers//VirtualMedia//Actions/" "VirtualMedia.InsertMedia") - .privileges({{"ConfigureManager"}}) + .privileges(redfish::privileges::postVirtualMedia) -- -2.25.1 +2.17.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend index b448121bf..0a7d18085 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -1,16 +1,16 @@ SRC_URI = "git://github.com/openbmc/bmcweb.git" -SRCREV = "e6a716506447d2d03b99f1cd2007e207a6dfcae0" +SRCREV = "abb93cdd0a49be03bf2fe95f07823686b289ecd5" DEPENDS += "boost-url" -RDEPENDS_${PN} += "phosphor-nslcd-authority-cert-config" +RDEPENDS:${PN} += "phosphor-nslcd-authority-cert-config" -FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" # add a user called bmcweb for the server to assume # bmcweb is part of group shadow for non-root pam authentication -USERADD_PARAM_${PN} = "-r -s /usr/sbin/nologin -d /home/bmcweb -m -G shadow bmcweb" +USERADD_PARAM:${PN} = "-r -s /usr/sbin/nologin -d /home/bmcweb -m -G shadow bmcweb" -GROUPADD_PARAM_${PN} = "web; redfish " +GROUPADD_PARAM:${PN} = "web; redfish " SRC_URI += "file://0001-Firmware-update-configuration-changes.patch \ file://0002-Use-chip-id-based-UUID-for-Service-Root.patch \ @@ -28,7 +28,6 @@ SRC_URI += "file://0001-Firmware-update-configuration-changes.patch \ file://0021-Add-message-registry-entry-for-FirmwareResiliencyErr.patch \ file://0023-Add-get-IPMI-session-id-s-to-Redfish.patch \ file://0024-Add-count-sensor-type.patch \ - file://0025-Revert-Support-new-boot-override-setting-design.patch \ " # OOB Bios Config: @@ -63,15 +62,17 @@ SRC_URI += "file://eventservice/0001-EventService-Fix-retry-handling-for-http-cl # Temporary downstream mirror of upstream patches, see telemetry\README for details SRC_URI += " file://telemetry/0001-Add-support-for-MetricDefinition-scheme.patch \ file://telemetry/0002-Sync-Telmetry-service-with-EventService.patch \ - file://telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch \ - file://telemetry/0004-event-service-fix-added-Context-field-to-response.patch \ - file://telemetry/0005-Switched-bmcweb-to-use-new-telemetry-service-API.patch \ - file://telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch \ - file://telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch \ + file://telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch \ + file://telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch \ + file://telemetry/0005-Add-DELETE-method-for-MetricReport.patch \ + file://telemetry/0006-Add-GET-method-for-TriggerCollection.patch \ + file://telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch \ + file://telemetry/0008-event-service-fix-added-Context-field-to-response.patch \ + file://telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch \ " # Temporary fix: Move it to service file -do_install_append() { +do_install:append() { install -d ${D}/var/lib/bmcweb install -d ${D}/etc/ssl/certs/authority } @@ -84,6 +85,6 @@ EXTRA_OEMESON += " -Dvm-nbdproxy=enabled" # Disable dependency on external nbd-proxy application EXTRA_OEMESON += " -Dvm-websocket=disabled" -RDEPENDS_${PN}_remove += "jsnbd" +RDEPENDS:${PN}:remove += "jsnbd" -- cgit v1.2.3