Memory: add health support

This adds health support to dimms. It also updates
the health object to look for an individual inventory
items health.

Tested:

Validator passed

{
    "@odata.id": "/redfish/v1/Systems/system/Memory/memory_device11",
    "@odata.type": "#Memory.v1_6_0.Memory",
    "CapacityMiB": 129728,
    "DataWidthBits": 64,
    "Id": "memory_device11",
    "Manufacturer": "Intel",
    "MemoryDeviceType": "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical",
    "Name": "DIMM Slot",
    "PartNumber": "",
    "SerialNumber": "",
    "Status": {
        "Health": "Critical",
        "HealthRollup": "Critical",
        "State": "Enabled"
    }
}

Change-Id: If2e1450b4228036f00ff78e6484e8da409a8039b
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/redfish-core/lib/health.hpp b/redfish-core/lib/health.hpp
index fe65ebf..b9f2e38 100644
--- a/redfish-core/lib/health.hpp
+++ b/redfish-core/lib/health.hpp
@@ -56,9 +56,11 @@
         for (const auto &[path, interfaces] : statuses)
         {
             bool isChild = false;
+            bool isSelf =
+                selfPath ? boost::starts_with(path.str, *selfPath) : false;
 
             // managers inventory is all the inventory, don't skip any
-            if (!isManagersHealth)
+            if (!isManagersHealth && !isSelf)
             {
 
                 // We only want to look at this association if either the path
@@ -133,6 +135,11 @@
             else if (boost::ends_with(path.str, "critical"))
             {
                 rollup = "Critical";
+                if (isSelf)
+                {
+                    health = "Critical";
+                    return;
+                }
             }
             else if (boost::ends_with(path.str, "warning"))
             {
@@ -140,6 +147,11 @@
                 {
                     rollup = "Warning";
                 }
+
+                if (isSelf)
+                {
+                    health = "Warning";
+                }
             }
         }
     }
@@ -211,6 +223,10 @@
     // destroyed last, and they need not call populate()
     std::vector<std::shared_ptr<HealthPopulate>> children;
 
+    // self is used if health is for an individual items status, as this is the
+    // 'lowest most' item, the rollup will equal the health
+    std::optional<std::string> selfPath;
+
     std::vector<std::string> inventory;
     bool isManagersHealth = false;
     dbus::utility::ManagedObjectType statuses;