Find the error logs that have a certain callout

In order to find the error logs that have a specific callout,
the code needs to look in the 'endpoints' property of the
'<callout>/fault' D-Bus object.

Change-Id: Idb9c06a6d815195ed47fb6ec914ba8f89539cb85
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/src/resolve_errors.cpp b/src/resolve_errors.cpp
index c08e489..6f3c4be 100644
--- a/src/resolve_errors.cpp
+++ b/src/resolve_errors.cpp
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <phosphor-logging/log.hpp>
 #include "resolve_errors.hpp"
+#include "sdbusplus.hpp"
 
 namespace phosphor
 {
@@ -22,9 +24,57 @@
 namespace monitoring
 {
 
+constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
+constexpr auto ASSOCIATION_IFACE = "org.openbmc.Association";
+constexpr auto ENDPOINTS_PROPERTY = "endpoints";
+
+using namespace phosphor::logging;
+using EndpointList = std::vector<std::string>;
+using EndpointsProperty = sdbusplus::message::variant<EndpointList>;
+
 void ResolveCallout::operator()()
 {
-    //TODO: fill in
+    //Resolve all errors for this callout:
+    // 1) Read the 'endpoints' property for the callout/fault object
+    //
+    // 2) Follow each endpoint to its log entry
+    //
+    // 3) Set the Resolved property to true on the entry
+
+    try
+    {
+        auto path = callout + "/fault";
+        auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE);
+
+        if (busName.empty())
+        {
+            //Just means there are no error logs with this callout
+            return;
+        }
+
+        auto endpoints = SDBusPlus::callMethodAndRead<EndpointsProperty>(
+                busName,
+                path,
+                PROPERTY_IFACE,
+                "Get",
+                ASSOCIATION_IFACE,
+                ENDPOINTS_PROPERTY);
+
+        const auto& logEntries = endpoints.get<EndpointList>();
+
+        //Resolve each log entry
+        for (const auto& logEntry : logEntries)
+        {
+            resolve(logEntry);
+        }
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>(
+                "Failed getting callout fault associations",
+                entry("CALLOUT=%s", callout.c_str()),
+                entry("MESSAGE=%s", e.what()));
+    }
 }
 
 void ResolveCallout::resolve(const std::string& logEntry)