control: Add loading JSON configuration class objects

Created a utility function to load the JSON configuration class objects
of a given type that can be used when building the zone groups.
Initially the fan control profiles are being loaded to be used later in
constructing the zone groups.

Tested:
    Profiles parsed successfully
    Map of parsed profiles available for creating zone groups

Change-Id: I379a46a2ecd17e4e4295131f75ca69b4f371348e
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/json_parser.cpp b/control/json_parser.cpp
index 3a0e7c2..9b80706 100644
--- a/control/json_parser.cpp
+++ b/control/json_parser.cpp
@@ -16,6 +16,7 @@
 #include "json_parser.hpp"
 
 #include "json/manager.hpp"
+#include "json/profile.hpp"
 #include "types.hpp"
 
 #include <sdbusplus/bus.hpp>
@@ -27,6 +28,11 @@
 {
     std::vector<ZoneGroup> zoneGrps;
 
+    // Profiles are optional
+    auto profiles = getConfig<json::Profile>(bus, true);
+
+    // TODO Create zone groups after loading all JSON config files
+
     return zoneGrps;
 }
 
diff --git a/control/json_parser.hpp b/control/json_parser.hpp
index 4b4801b..29d1697 100644
--- a/control/json_parser.hpp
+++ b/control/json_parser.hpp
@@ -15,16 +15,53 @@
  */
 #pragma once
 
+#include "json/profile.hpp"
+#include "json_config.hpp"
 #include "types.hpp"
 
+#include <nlohmann/json.hpp>
 #include <sdbusplus/bus.hpp>
 
+#include <map>
+#include <memory>
+
 namespace phosphor::fan::control
 {
 
+/* Application name to be appended to the path for loading a JSON config file */
 constexpr auto confAppName = "control";
 
 /**
+ * @brief Load the configuration of a given JSON class object type
+ *
+ * @param[in] bus - The dbus bus object
+ * @param[in] isOptional - JSON configuration file is optional or not
+ *                         Defaults to false
+ *
+ * @return Map of configuration entries
+ *     Map of configuration names to their corresponding configuration object
+ */
+template <typename T>
+std::map<std::string, std::unique_ptr<T>> getConfig(sdbusplus::bus::bus& bus,
+                                                    bool isOptional = false)
+{
+    std::map<std::string, std::unique_ptr<T>> config;
+
+    auto confFile = fan::JsonConfig::getConfFile(bus, confAppName,
+                                                 T::confFileName, isOptional);
+    if (!confFile.empty())
+    {
+        for (const auto& entry : fan::JsonConfig::load(confFile))
+        {
+            auto obj = std::make_unique<T>(bus, entry);
+            config.emplace(obj->getName(), std::move(obj));
+        }
+    }
+
+    return config;
+}
+
+/**
  * @brief Get the configuration definitions for zone groups
  *
  * @param[in] bus - The dbus bus object