More PDR refactor

- PDRs can be created not just by the platform monitoring and control
  handlers, but by other handlers (eg FRU) as well.
- For this purpose, create the PDR repo in the pldm daemon, and pass it
  to the handlers. This change warranted some refactor.

Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Change-Id: I4e789da9bae99dee1b535d92ce98ae5bb8eed62b
Signed-off-by: George Liu <liuxiwei@inspur.com>
diff --git a/libpldmresponder/effecters.cpp b/libpldmresponder/effecters.cpp
deleted file mode 100644
index a48582b..0000000
--- a/libpldmresponder/effecters.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "effecters.hpp"
-
-#include <map>
-
-namespace pldm
-{
-
-namespace responder
-{
-
-namespace effecter
-{
-
-Id nextId()
-{
-    static Id id = 0;
-    return ++id;
-}
-
-namespace dbus_mapping
-{
-
-namespace internal
-{
-
-std::map<Id, Paths> idToDbus{};
-
-} // namespace internal
-
-void add(Id id, Paths&& paths)
-{
-    internal::idToDbus.emplace(id, std::move(paths));
-}
-
-Paths get(Id id)
-{
-    return internal::idToDbus.at(id);
-}
-
-} // namespace dbus_mapping
-
-} // namespace effecter
-} // namespace responder
-} // namespace pldm
diff --git a/libpldmresponder/effecters.hpp b/libpldmresponder/effecters.hpp
deleted file mode 100644
index 2dfa1f5..0000000
--- a/libpldmresponder/effecters.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-#include <string>
-#include <vector>
-
-namespace pldm
-{
-
-namespace responder
-{
-
-namespace effecter
-{
-
-using Id = uint16_t;
-
-/** @brief Get next available id to assign to an effecter
- *
- *  @return  uint16_t - effecter id
- */
-Id nextId();
-
-namespace dbus_mapping
-{
-using Paths = std::vector<std::string>;
-
-/** @brief Add an effecter id -> D-Bus objects mapping
- *
- *  @param[in] id - effecter id
- *  @param[in] paths - list of D-Bus object paths
- */
-void add(Id id, Paths&& paths);
-
-/** @brief Retrieve an effecter id -> D-Bus objects mapping
- *
- *  @param[in] id - effecter id
- *
- *  @return Paths - list of D-Bus object paths
- */
-Paths get(Id id);
-} // namespace dbus_mapping
-
-} // namespace effecter
-} // namespace responder
-} // namespace pldm
diff --git a/libpldmresponder/meson.build b/libpldmresponder/meson.build
index ab3aeb4..3f09ee7 100644
--- a/libpldmresponder/meson.build
+++ b/libpldmresponder/meson.build
@@ -12,7 +12,6 @@
   'bios_parser.cpp',
   'pdr_utils.cpp',
   'pdr.cpp',
-  'effecters.cpp',
   'platform.cpp',
   'fru_parser.cpp',
   'fru.cpp'
diff --git a/libpldmresponder/pdr.cpp b/libpldmresponder/pdr.cpp
index d2c8214..27a0bd3 100644
--- a/libpldmresponder/pdr.cpp
+++ b/libpldmresponder/pdr.cpp
@@ -1,5 +1,7 @@
 #include "pdr.hpp"
 
+#include "platform.hpp"
+
 namespace pldm
 {
 
@@ -8,180 +10,31 @@
 
 namespace pdr
 {
+
 using namespace pldm::responder::pdr_utils;
 
-void generate(const std::string& dir, RepoInterface& repo)
+void getRepoByType(const Repo& inRepo, Repo& outRepo, Type pdrType)
 {
-    // A map of PDR type to a lambda that handles creation of that PDR type.
-    // The lambda essentially would parse the platform specific PDR JSONs to
-    // generate the PDR structures. This function iterates through the map to
-    // invoke all lambdas, so that all PDR types can be created.
-    std::map<Type, std::function<void(const Json& json, RepoInterface& repo)>>
-        generators = {
-            {PLDM_STATE_EFFECTER_PDR,
-             [](const auto& json, RepoInterface& repo) {
-                 static const std::vector<Json> emptyList{};
-                 static const Json empty{};
-                 auto entries = json.value("entries", emptyList);
-                 for (const auto& e : entries)
-                 {
-                     size_t pdrSize = 0;
-                     auto effecters = e.value("effecters", emptyList);
-                     static const Json empty{};
-                     for (const auto& effecter : effecters)
-                     {
-                         auto set = effecter.value("set", empty);
-                         auto statesSize = set.value("size", 0);
-                         if (!statesSize)
-                         {
-                             std::cerr << "Malformed PDR JSON return "
-                                          "pdrEntry;- no state set "
-                                          "info, TYPE="
-                                       << PLDM_STATE_EFFECTER_PDR << "\n";
-                             throw InternalFailure();
-                         }
-                         pdrSize += sizeof(state_effecter_possible_states) -
-                                    sizeof(bitfield8_t) +
-                                    (sizeof(bitfield8_t) * statesSize);
-                     }
-                     pdrSize +=
-                         sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
-
-                     std::vector<uint8_t> entry{};
-                     entry.resize(pdrSize);
-
-                     pldm_state_effecter_pdr* pdr =
-                         reinterpret_cast<pldm_state_effecter_pdr*>(
-                             entry.data());
-                     pdr->hdr.record_handle = 0;
-                     pdr->hdr.version = 1;
-                     pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
-                     pdr->hdr.record_change_num = 0;
-                     pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
-
-                     pdr->terminus_handle = 0;
-                     pdr->effecter_id = effecter::nextId();
-                     pdr->entity_type = e.value("type", 0);
-                     pdr->entity_instance = e.value("instance", 0);
-                     pdr->container_id = e.value("container", 0);
-                     pdr->effecter_semantic_id = 0;
-                     pdr->effecter_init = PLDM_NO_INIT;
-                     pdr->has_description_pdr = false;
-                     pdr->composite_effecter_count = effecters.size();
-
-                     using namespace effecter::dbus_mapping;
-                     Paths paths{};
-                     uint8_t* start = entry.data() +
-                                      sizeof(pldm_state_effecter_pdr) -
-                                      sizeof(uint8_t);
-                     for (const auto& effecter : effecters)
-                     {
-                         auto set = effecter.value("set", empty);
-                         state_effecter_possible_states* possibleStates =
-                             reinterpret_cast<state_effecter_possible_states*>(
-                                 start);
-                         possibleStates->state_set_id = set.value("id", 0);
-                         possibleStates->possible_states_size =
-                             set.value("size", 0);
-
-                         start += sizeof(possibleStates->state_set_id) +
-                                  sizeof(possibleStates->possible_states_size);
-                         static const std::vector<uint8_t> emptyStates{};
-                         auto states = set.value("states", emptyStates);
-                         for (const auto& state : states)
-                         {
-                             auto index = state / 8;
-                             auto bit = state - (index * 8);
-                             bitfield8_t* bf =
-                                 reinterpret_cast<bitfield8_t*>(start + index);
-                             bf->byte |= 1 << bit;
-                         }
-                         start += possibleStates->possible_states_size;
-
-                         auto dbus = effecter.value("dbus", empty);
-                         paths.emplace_back(std::move(dbus));
-                     }
-                     add(pdr->effecter_id, std::move(paths));
-                     PdrEntry pdrEntry{};
-                     pdrEntry.data = entry.data();
-                     pdrEntry.size = pdrSize;
-                     repo.addRecord(pdrEntry);
-                 }
-             }}};
-
-    Type pdrType{};
-    for (const auto& dirEntry : fs::directory_iterator(dir))
-    {
-        try
-        {
-            auto json = readJson(dirEntry.path().string());
-            if (!json.empty())
-            {
-                pdrType = json.value("pdrType", 0);
-                generators.at(pdrType)(json, repo);
-            }
-        }
-        catch (const InternalFailure& e)
-        {
-            std::cerr << "PDR config directory does not exist or empty, TYPE= "
-                      << pdrType << "PATH= " << dirEntry
-                      << " ERROR=" << e.what() << "\n";
-        }
-        catch (const Json::exception& e)
-        {
-            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
-                      << "PATH= " << dirEntry << " ERROR=" << e.what() << "\n";
-            pldm::utils::reportError(
-                "xyz.openbmc_project.bmc.pldm.InternalFailure");
-        }
-        catch (const std::exception& e)
-        {
-            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
-                      << " ERROR=" << e.what() << "\n";
-            pldm::utils::reportError(
-                "xyz.openbmc_project.bmc.pldm.InternalFailure");
-        }
-    }
-}
-
-RepoInterface& getRepo(const std::string& dir)
-{
-    static Repo repo;
-    if (repo.empty())
-    {
-        generate(dir, repo);
-    }
-
-    return repo;
-}
-
-Repo getRepoByType(const std::string& dir, Type pdrType)
-{
-    Repo pdrRepo;
-    RepoInterface& repo = getRepo(dir);
-
     uint8_t* pdrData = nullptr;
     uint32_t pdrSize{};
-    auto record = pldm_pdr_find_record_by_type(repo.getPdr(), pdrType, NULL,
+    auto record = pldm_pdr_find_record_by_type(inRepo.getPdr(), pdrType, NULL,
                                                &pdrData, &pdrSize);
     while (record)
     {
         PdrEntry pdrEntry{};
         pdrEntry.data = pdrData;
         pdrEntry.size = pdrSize;
-        pdrEntry.handle.recordHandle = repo.getRecordHandle(record);
-        pdrRepo.addRecord(pdrEntry);
+        pdrEntry.handle.recordHandle = inRepo.getRecordHandle(record);
+        outRepo.addRecord(pdrEntry);
 
         pdrData = nullptr;
         pdrSize = 0;
-        record = pldm_pdr_find_record_by_type(repo.getPdr(), pdrType, record,
+        record = pldm_pdr_find_record_by_type(inRepo.getPdr(), pdrType, record,
                                               &pdrData, &pdrSize);
     }
-
-    return pdrRepo;
 }
 
-const pldm_pdr_record* getRecordByHandle(RepoInterface& pdrRepo,
+const pldm_pdr_record* getRecordByHandle(const RepoInterface& pdrRepo,
                                          RecordHandle recordHandle,
                                          PdrEntry& pdrEntry)
 {
diff --git a/libpldmresponder/pdr.hpp b/libpldmresponder/pdr.hpp
index 0cf9385..78925f7 100644
--- a/libpldmresponder/pdr.hpp
+++ b/libpldmresponder/pdr.hpp
@@ -1,27 +1,12 @@
 #pragma once
 
-#include "effecters.hpp"
 #include "libpldmresponder/pdr_utils.hpp"
-#include "utils.hpp"
 
 #include <stdint.h>
 
-#include <filesystem>
-#include <fstream>
-#include <functional>
-#include <iostream>
-#include <map>
-#include <nlohmann/json.hpp>
 #include <string>
-#include <vector>
-#include <xyz/openbmc_project/Common/error.hpp>
 
 #include "libpldm/pdr.h"
-#include "libpldm/platform.h"
-
-using InternalFailure =
-    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
-namespace fs = std::filesystem;
 
 using namespace pldm::responder::pdr_utils;
 
@@ -33,20 +18,6 @@
 
 namespace pdr
 {
-/** @brief Parse PDR JSONs and build PDR repository
- *
- *  @param[in] dir - directory housing platform specific PDR JSON files
- *  @param[in] repo - instance of the concrete implementation of RepoInterface
- */
-void generate(const std::string& dir, RepoInterface& repo);
-
-/** @brief Build (if not built already) and retrieve PDR
- *
- *  @param[in] dir - directory housing platform specific PDR JSON files
- *
- *  @return RepoInterface& - Reference to instance of pdr::RepoInterface
- */
-RepoInterface& getRepo(const std::string& dir);
 
 /** @brief Build (if not built already) and retrieve PDR by the PDR types
  *
@@ -55,7 +26,7 @@
  *
  *  @return Repo - Instance of pdr::Repo
  */
-Repo getRepoByType(const std::string& dir, Type pdrType);
+void getRepoByType(const Repo& inRepo, Repo& outRepo, Type pdrType);
 
 /** @brief Get the record of PDR by the record handle
  *
@@ -66,7 +37,7 @@
  *
  *  @return pldm_pdr_record - Instance of pdr::RepoInterface
  */
-const pldm_pdr_record* getRecordByHandle(RepoInterface& pdrRepo,
+const pldm_pdr_record* getRecordByHandle(const RepoInterface& pdrRepo,
                                          RecordHandle recordHandle,
                                          PdrEntry& pdrEntry);
 
diff --git a/libpldmresponder/pdr_utils.cpp b/libpldmresponder/pdr_utils.cpp
index 850dbcb..9a68ca9 100644
--- a/libpldmresponder/pdr_utils.cpp
+++ b/libpldmresponder/pdr_utils.cpp
@@ -9,7 +9,7 @@
 namespace pdr_utils
 {
 
-const pldm_pdr* Repo::getPdr()
+pldm_pdr* Repo::getPdr() const
 {
     return repo;
 }
@@ -50,7 +50,7 @@
     return record;
 }
 
-uint32_t Repo::getRecordHandle(const pldm_pdr_record* record)
+uint32_t Repo::getRecordHandle(const pldm_pdr_record* record) const
 {
     return pldm_pdr_get_record_handle(getPdr(), record);
 }
diff --git a/libpldmresponder/pdr_utils.hpp b/libpldmresponder/pdr_utils.hpp
index 4c2af02..0c3f634 100644
--- a/libpldmresponder/pdr_utils.hpp
+++ b/libpldmresponder/pdr_utils.hpp
@@ -77,13 +77,17 @@
 class RepoInterface
 {
   public:
+    RepoInterface(pldm_pdr* repo) : repo(repo)
+    {
+    }
+
     virtual ~RepoInterface() = default;
 
     /** @brief Get an opaque pldm_pdr structure
      *
      *  @return pldm_pdr - pldm_pdr structure
      */
-    virtual const pldm_pdr* getPdr() = 0;
+    virtual pldm_pdr* getPdr() const = 0;
 
     /** @brief Add a PDR record to a PDR repository
      *
@@ -121,7 +125,7 @@
      *  @return uint32_t - record handle assigned to PDR record; 0 if record is
      *                     not found
      */
-    virtual uint32_t getRecordHandle(const pldm_pdr_record* record) = 0;
+    virtual uint32_t getRecordHandle(const pldm_pdr_record* record) const = 0;
 
     /** @brief Get number of records in a PDR repository
      *
@@ -149,30 +153,24 @@
 class Repo : public RepoInterface
 {
   public:
-    Repo()
+    Repo(pldm_pdr* repo) : RepoInterface(repo)
     {
-        repo = pldm_pdr_init();
     }
 
-    ~Repo()
-    {
-        pldm_pdr_destroy(repo);
-    }
+    pldm_pdr* getPdr() const override;
 
-    const pldm_pdr* getPdr();
+    RecordHandle addRecord(const PdrEntry& pdrEntry) override;
 
-    RecordHandle addRecord(const PdrEntry& pdrEntry);
-
-    const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry);
+    const pldm_pdr_record* getFirstRecord(PdrEntry& pdrEntry) override;
 
     const pldm_pdr_record* getNextRecord(const pldm_pdr_record* currRecord,
-                                         PdrEntry& pdrEntry);
+                                         PdrEntry& pdrEntry) override;
 
-    uint32_t getRecordHandle(const pldm_pdr_record* record);
+    uint32_t getRecordHandle(const pldm_pdr_record* record) const override;
 
-    uint32_t getRecordCount();
+    uint32_t getRecordCount() override;
 
-    bool empty();
+    bool empty() override;
 };
 
 } // namespace pdr_utils
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index 4d297f0..4cad1d6 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -10,7 +10,138 @@
 namespace platform
 {
 
-using namespace pldm::responder::effecter::dbus_mapping;
+using InternalFailure =
+    sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+
+void Handler::generateStateEffecterRepo(const Json& json, Repo& repo)
+{
+    static const std::vector<Json> emptyList{};
+    static const Json empty{};
+    auto entries = json.value("entries", emptyList);
+    for (const auto& e : entries)
+    {
+        size_t pdrSize = 0;
+        auto effecters = e.value("effecters", emptyList);
+        static const Json empty{};
+        for (const auto& effecter : effecters)
+        {
+            auto set = effecter.value("set", empty);
+            auto statesSize = set.value("size", 0);
+            if (!statesSize)
+            {
+                std::cerr << "Malformed PDR JSON return "
+                             "pdrEntry;- no state set "
+                             "info, TYPE="
+                          << PLDM_STATE_EFFECTER_PDR << "\n";
+                throw InternalFailure();
+            }
+            pdrSize += sizeof(state_effecter_possible_states) -
+                       sizeof(bitfield8_t) + (sizeof(bitfield8_t) * statesSize);
+        }
+        pdrSize += sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
+
+        std::vector<uint8_t> entry{};
+        entry.resize(pdrSize);
+
+        pldm_state_effecter_pdr* pdr =
+            reinterpret_cast<pldm_state_effecter_pdr*>(entry.data());
+        pdr->hdr.record_handle = 0;
+        pdr->hdr.version = 1;
+        pdr->hdr.type = PLDM_STATE_EFFECTER_PDR;
+        pdr->hdr.record_change_num = 0;
+        pdr->hdr.length = pdrSize - sizeof(pldm_pdr_hdr);
+
+        pdr->terminus_handle = 0;
+        pdr->effecter_id = this->getNextEffecterId();
+        pdr->entity_type = e.value("type", 0);
+        pdr->entity_instance = e.value("instance", 0);
+        pdr->container_id = e.value("container", 0);
+        pdr->effecter_semantic_id = 0;
+        pdr->effecter_init = PLDM_NO_INIT;
+        pdr->has_description_pdr = false;
+        pdr->composite_effecter_count = effecters.size();
+
+        EffecterObjs paths{};
+        uint8_t* start =
+            entry.data() + sizeof(pldm_state_effecter_pdr) - sizeof(uint8_t);
+        for (const auto& effecter : effecters)
+        {
+            auto set = effecter.value("set", empty);
+            state_effecter_possible_states* possibleStates =
+                reinterpret_cast<state_effecter_possible_states*>(start);
+            possibleStates->state_set_id = set.value("id", 0);
+            possibleStates->possible_states_size = set.value("size", 0);
+
+            start += sizeof(possibleStates->state_set_id) +
+                     sizeof(possibleStates->possible_states_size);
+            static const std::vector<uint8_t> emptyStates{};
+            auto states = set.value("states", emptyStates);
+            for (const auto& state : states)
+            {
+                auto index = state / 8;
+                auto bit = state - (index * 8);
+                bitfield8_t* bf = reinterpret_cast<bitfield8_t*>(start + index);
+                bf->byte |= 1 << bit;
+            }
+            start += possibleStates->possible_states_size;
+
+            auto dbus = effecter.value("dbus", empty);
+            paths.emplace_back(std::move(dbus));
+        }
+        addEffecterObjs(pdr->effecter_id, std::move(paths));
+        PdrEntry pdrEntry{};
+        pdrEntry.data = entry.data();
+        pdrEntry.size = pdrSize;
+        repo.addRecord(pdrEntry);
+    }
+}
+
+void Handler::generate(const std::string& dir, Repo& repo)
+{
+    // A map of PDR type to a lambda that handles creation of that PDR type.
+    // The lambda essentially would parse the platform specific PDR JSONs to
+    // generate the PDR structures. This function iterates through the map to
+    // invoke all lambdas, so that all PDR types can be created.
+    const std::map<Type, std::function<void(const Json& json, Repo& repo)>>
+        generators = {
+            {PLDM_STATE_EFFECTER_PDR, [this](const auto& json, Repo& repo) {
+                 generateStateEffecterRepo(json, repo);
+             }}};
+
+    Type pdrType{};
+    for (const auto& dirEntry : fs::directory_iterator(dir))
+    {
+        try
+        {
+            auto json = readJson(dirEntry.path().string());
+            if (!json.empty())
+            {
+                pdrType = json.value("pdrType", 0);
+                generators.at(pdrType)(json, repo);
+            }
+        }
+        catch (const InternalFailure& e)
+        {
+            std::cerr << "PDR config directory does not exist or empty, TYPE= "
+                      << pdrType << "PATH= " << dirEntry
+                      << " ERROR=" << e.what() << "\n";
+        }
+        catch (const Json::exception& e)
+        {
+            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
+                      << " ERROR=" << e.what() << "\n";
+            pldm::utils::reportError(
+                "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        }
+        catch (const std::exception& e)
+        {
+            std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
+                      << " ERROR=" << e.what() << "\n";
+            pldm::utils::reportError(
+                "xyz.openbmc_project.bmc.pldm.InternalFailure");
+        }
+    }
+}
 
 Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
 {
@@ -40,7 +171,6 @@
     uint8_t* recordData = nullptr;
     try
     {
-        pdr_utils::RepoInterface& pdrRepo = pdr::getRepo(PDR_JSONS_DIR);
         pdr_utils::PdrEntry e;
         auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
         if (record == NULL)
diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index dde51e0..8bcc596 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -21,11 +21,16 @@
 namespace platform
 {
 
+using DbusPath = std::string;
+using EffecterObjs = std::vector<DbusPath>;
+
 class Handler : public CmdHandler
 {
   public:
-    Handler()
+    Handler(const std::string& dir, pldm_pdr* repo) : pdrRepo(repo)
     {
+        generate(dir, pdrRepo);
+
         handlers.emplace(PLDM_GET_PDR,
                          [this](const pldm_msg* request, size_t payloadLength) {
                              return this->getPDR(request, payloadLength);
@@ -37,6 +42,35 @@
                          });
     }
 
+    const EffecterObjs& getEffecterObjs(uint16_t effecterId) const
+    {
+        return effecterObjs.at(effecterId);
+    }
+
+    void addEffecterObjs(uint16_t effecterId, EffecterObjs&& paths)
+    {
+        effecterObjs.emplace(effecterId, std::move(paths));
+    }
+
+    uint16_t getNextEffecterId()
+    {
+        return ++nextEffecterId;
+    }
+
+    /** @brief Parse PDR JSONs and build PDR repository
+     *
+     *  @param[in] dir - directory housing platform specific PDR JSON files
+     *  @param[in] repo - instance of concrete implementation of Repo
+     */
+    void generate(const std::string& dir, Repo& repo);
+
+    /** @brief Parse PDR JSONs and build state effecter PDR repository
+     *
+     *  @param[in] json - platform specific PDR JSON files
+     *  @param[in] repo - instance of state effecter implementation of Repo
+     */
+    void generateStateEffecterRepo(const Json& json, Repo& repo);
+
     /** @brief Handler for GetPDR
      *
      *  @param[in] request - Request message payload
@@ -64,7 +98,7 @@
      */
     template <class DBusInterface>
     int setStateEffecterStatesHandler(
-        const DBusInterface& dBusIntf, effecter::Id effecterId,
+        const DBusInterface& dBusIntf, uint16_t effecterId,
         const std::vector<set_effecter_state_field>& stateField)
     {
         using namespace pldm::responder::pdr;
@@ -86,28 +120,19 @@
              {{PLDM_OFF_SOFT_GRACEFUL,
                "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
         using namespace pldm::responder::pdr;
-        using namespace pldm::responder::effecter::dbus_mapping;
 
         state_effecter_possible_states* states = nullptr;
         pldm_state_effecter_pdr* pdr = nullptr;
         uint8_t compEffecterCnt = stateField.size();
-
-        pdr_utils::Repo repo =
-            getRepoByType(PDR_JSONS_DIR, PLDM_STATE_EFFECTER_PDR);
-        if (repo.empty())
-        {
-            std::cerr << "Failed to get record by PDR type\n";
-            return PLDM_PLATFORM_INVALID_EFFECTER_ID;
-        }
         PdrEntry pdrEntry{};
-        auto pdrRecord = repo.getFirstRecord(pdrEntry);
+        auto pdrRecord = pdrRepo.getFirstRecord(pdrEntry);
         while (pdrRecord)
         {
             pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data);
             if (pdr->effecter_id != effecterId)
             {
                 pdr = nullptr;
-                pdrRecord = repo.getNextRecord(pdrRecord, pdrEntry);
+                pdrRecord = pdrRepo.getNextRecord(pdrRecord, pdrEntry);
                 continue;
             }
 
@@ -223,7 +248,7 @@
                  }}};
 
         int rc = PLDM_SUCCESS;
-        auto paths = get(effecterId);
+        const auto& paths = getEffecterObjs(effecterId);
         for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
         {
             std::vector<StateSetNum> allowed{};
@@ -270,6 +295,11 @@
         }
         return rc;
     }
+
+  private:
+    pdr_utils::Repo pdrRepo;
+    uint16_t nextEffecterId{};
+    std::map<uint16_t, EffecterObjs> effecterObjs{};
 };
 
 } // namespace platform
diff --git a/pldmd.cpp b/pldmd.cpp
index a13383d..6ddbcde 100644
--- a/pldmd.cpp
+++ b/pldmd.cpp
@@ -20,6 +20,7 @@
 #include <iomanip>
 #include <iostream>
 #include <iterator>
+#include <memory>
 #include <sdeventplus/event.hpp>
 #include <sdeventplus/source/io.hpp>
 #include <sstream>
@@ -29,6 +30,7 @@
 
 #include "libpldm/base.h"
 #include "libpldm/bios.h"
+#include "libpldm/pdr.h"
 #include "libpldm/platform.h"
 
 #ifdef OEM_IBM
@@ -144,11 +146,14 @@
             break;
     }
 
+    std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> pdrRepo(
+        pldm_pdr_init(), pldm_pdr_destroy);
+
     Invoker invoker{};
     invoker.registerHandler(PLDM_BASE, std::make_unique<base::Handler>());
     invoker.registerHandler(PLDM_BIOS, std::make_unique<bios::Handler>());
-    invoker.registerHandler(PLDM_PLATFORM,
-                            std::make_unique<platform::Handler>());
+    invoker.registerHandler(PLDM_PLATFORM, std::make_unique<platform::Handler>(
+                                               PDR_JSONS_DIR, pdrRepo.get()));
     invoker.registerHandler(PLDM_FRU,
                             std::make_unique<fru::Handler>(FRU_JSONS_DIR));
 
diff --git a/test/libpldmresponder_pdr_state_effecter_test.cpp b/test/libpldmresponder_pdr_state_effecter_test.cpp
index c2b114c..5c197dd 100644
--- a/test/libpldmresponder_pdr_state_effecter_test.cpp
+++ b/test/libpldmresponder_pdr_state_effecter_test.cpp
@@ -1,25 +1,30 @@
-#include "libpldmresponder/effecters.hpp"
-#include "libpldmresponder/pdr.hpp"
 #include "libpldmresponder/pdr_utils.hpp"
+#include "libpldmresponder/platform.hpp"
 
 #include "libpldm/platform.h"
 
 #include <gtest/gtest.h>
 
 using namespace pldm::responder;
+using namespace pldm::responder::platform;
+using namespace pldm::responder::pdr;
+using namespace pldm::responder::pdr_utils;
 
 TEST(GeneratePDR, testGoodJson)
 {
-    using namespace effecter::dbus_mapping;
-    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
-        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    auto inPDRRepo = pldm_pdr_init();
+    auto outPDRRepo = pldm_pdr_init();
+    Repo outRepo(outPDRRepo);
+    Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
 
     // 2 entries
-    ASSERT_EQ(pdrRepo.getRecordCount(), 2);
+    ASSERT_EQ(outRepo.getRecordCount(), 2);
 
     // Check first PDR
     pdr_utils::PdrEntry e;
-    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    auto record1 = pdr::getRecordByHandle(outRepo, 1, e);
     ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
@@ -47,11 +52,11 @@
     bf1.byte = 2;
     ASSERT_EQ(states->states[0].byte, bf1.byte);
 
-    auto paths = get(pdr->effecter_id);
+    const auto& paths = handler.getEffecterObjs(pdr->effecter_id);
     ASSERT_EQ(paths[0], "/foo/bar");
 
     // Check second PDR
-    auto record2 = pdr::getRecordByHandle(pdrRepo, 2, e);
+    auto record2 = pdr::getRecordByHandle(outRepo, 2, e);
     ASSERT_NE(record2, nullptr);
     pdr = reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
 
@@ -86,23 +91,38 @@
     ASSERT_EQ(states->states[0].byte, bf2[0].byte);
     ASSERT_EQ(states->states[1].byte, bf2[1].byte);
 
-    paths = get(pdr->effecter_id);
-    ASSERT_EQ(paths[0], "/foo/bar");
-    ASSERT_EQ(paths[1], "/foo/bar/baz");
+    const auto& paths1 = handler.getEffecterObjs(pdr->effecter_id);
+    ASSERT_EQ(paths1[0], "/foo/bar");
+    ASSERT_EQ(paths1[1], "/foo/bar/baz");
 
-    ASSERT_THROW(get(0xDEAD), std::exception);
+    ASSERT_THROW(handler.getEffecterObjs(0xDEAD), std::exception);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(outPDRRepo);
 }
 
 TEST(GeneratePDR, testNoJson)
 {
-    ASSERT_THROW(pdr_utils::readJson("./pdr_jsons/not_there"), std::exception);
+    auto pdrRepo = pldm_pdr_init();
+
+    ASSERT_THROW(Handler("./pdr_jsons/not_there", pdrRepo), std::exception);
+
+    pldm_pdr_destroy(pdrRepo);
 }
 
 TEST(GeneratePDR, testMalformedJson)
 {
-    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
-        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
-    ASSERT_EQ(pdrRepo.getRecordCount(), 2);
+    auto inPDRRepo = pldm_pdr_init();
+    auto outPDRRepo = pldm_pdr_init();
+    Repo outRepo(outPDRRepo);
+    Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
+
+    ASSERT_EQ(outRepo.getRecordCount(), 2);
     ASSERT_THROW(pdr_utils::readJson("./pdr_jsons/state_effecter/malformed"),
                  std::exception);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(outPDRRepo);
 }
diff --git a/test/libpldmresponder_platform_test.cpp b/test/libpldmresponder_platform_test.cpp
index 8252920..d1241c2 100644
--- a/test/libpldmresponder_platform_test.cpp
+++ b/test/libpldmresponder_platform_test.cpp
@@ -1,4 +1,3 @@
-#include "libpldmresponder/effecters.hpp"
 #include "libpldmresponder/pdr.hpp"
 #include "libpldmresponder/pdr_utils.hpp"
 #include "libpldmresponder/platform.hpp"
@@ -10,6 +9,9 @@
 #include <gtest/gtest.h>
 
 using namespace pldm::responder;
+using namespace pldm::responder::platform;
+using namespace pldm::responder::pdr;
+using namespace pldm::responder::pdr_utils;
 
 TEST(getPDR, testGoodPath)
 {
@@ -22,10 +24,10 @@
         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
     request->request_count = 100;
 
-    pdr_utils::RepoInterface& pdrRepo =
-        pdr::getRepo("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.empty(), false);
-    platform::Handler handler;
+    auto pdrRepo = pldm_pdr_init();
+    Handler handler("./pdr_jsons/state_effecter/good", pdrRepo);
+    Repo repo(pdrRepo);
+    ASSERT_EQ(repo.empty(), false);
     auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
@@ -38,6 +40,8 @@
     pldm_pdr_hdr* hdr = reinterpret_cast<pldm_pdr_hdr*>(resp->record_data);
     ASSERT_EQ(hdr->record_handle, 1);
     ASSERT_EQ(hdr->version, 1);
+
+    pldm_pdr_destroy(pdrRepo);
 }
 
 TEST(getPDR, testShortRead)
@@ -51,16 +55,17 @@
         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
     request->request_count = 1;
 
-    pdr_utils::RepoInterface& pdrRepo =
-        pdr::getRepo("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.empty(), false);
-    platform::Handler handler;
+    auto pdrRepo = pldm_pdr_init();
+    Handler handler("./pdr_jsons/state_effecter/good", pdrRepo);
+    Repo repo(pdrRepo);
+    ASSERT_EQ(repo.empty(), false);
     auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_get_pdr_resp* resp =
         reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
     ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
     ASSERT_EQ(1, resp->response_count);
+    pldm_pdr_destroy(pdrRepo);
 }
 
 TEST(getPDR, testBadRecordHandle)
@@ -75,14 +80,16 @@
     request->record_handle = 100000;
     request->request_count = 1;
 
-    pdr_utils::RepoInterface& pdrRepo =
-        pdr::getRepo("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.empty(), false);
-    platform::Handler handler;
+    auto pdrRepo = pldm_pdr_init();
+    Handler handler("./pdr_jsons/state_effecter/good", pdrRepo);
+    Repo repo(pdrRepo);
+    ASSERT_EQ(repo.empty(), false);
     auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
 
     ASSERT_EQ(responsePtr->payload[0], PLDM_PLATFORM_INVALID_RECORD_HANDLE);
+
+    pldm_pdr_destroy(pdrRepo);
 }
 
 TEST(getPDR, testNoNextRecord)
@@ -96,16 +103,18 @@
         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
     request->record_handle = 1;
 
-    pdr_utils::RepoInterface& pdrRepo =
-        pdr::getRepo("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.empty(), false);
-    platform::Handler handler;
+    auto pdrRepo = pldm_pdr_init();
+    Handler handler("./pdr_jsons/state_effecter/good", pdrRepo);
+    Repo repo(pdrRepo);
+    ASSERT_EQ(repo.empty(), false);
     auto response = handler.getPDR(req, requestPayloadLength);
     auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
     struct pldm_get_pdr_resp* resp =
         reinterpret_cast<struct pldm_get_pdr_resp*>(responsePtr->payload);
     ASSERT_EQ(PLDM_SUCCESS, resp->completion_code);
     ASSERT_EQ(2, resp->next_record_handle);
+
+    pldm_pdr_destroy(pdrRepo);
 }
 
 TEST(getPDR, testFindPDR)
@@ -119,10 +128,10 @@
         reinterpret_cast<struct pldm_get_pdr_req*>(req->payload);
     request->request_count = 100;
 
-    pdr_utils::RepoInterface& pdrRepo =
-        pdr::getRepo("./pdr_jsons/state_effecter/good");
-    ASSERT_EQ(pdrRepo.empty(), false);
-    platform::Handler handler;
+    auto pdrRepo = pldm_pdr_init();
+    Handler handler("./pdr_jsons/state_effecter/good", pdrRepo);
+    Repo repo(pdrRepo);
+    ASSERT_EQ(repo.empty(), false);
     auto response = handler.getPDR(req, requestPayloadLength);
 
     // Let's try to find a PDR of type stateEffecter (= 11) and entity type =
@@ -132,7 +141,6 @@
     while (!found)
     {
         request->record_handle = handle;
-        platform::Handler handler;
         auto response = handler.getPDR(req, requestPayloadLength);
         auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
         struct pldm_get_pdr_resp* resp =
@@ -163,6 +171,8 @@
         }
     }
     ASSERT_EQ(found, true);
+
+    pldm_pdr_destroy(pdrRepo);
 }
 
 namespace pldm
@@ -187,10 +197,14 @@
 
 TEST(setStateEffecterStatesHandler, testGoodRequest)
 {
-    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
-        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    auto inPDRRepo = pldm_pdr_init();
+    auto outPDRRepo = pldm_pdr_init();
+    Repo outRepo(outPDRRepo);
+    Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
     pdr_utils::PdrEntry e;
-    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    auto record1 = pdr::getRecordByHandle(outRepo, 1, e);
     ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
@@ -210,18 +224,24 @@
     EXPECT_CALL(handlerObj, setDbusProperty(objPath, bootProgressProp,
                                             bootProgressInf, value))
         .Times(2);
-    platform::Handler handler;
     auto rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(
         handlerObj, 0x1, stateField);
     ASSERT_EQ(rc, 0);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(outPDRRepo);
 }
 
 TEST(setStateEffecterStatesHandler, testBadRequest)
 {
-    pdr_utils::Repo pdrRepo = pdr::getRepoByType(
-        "./pdr_jsons/state_effecter/good", PLDM_STATE_EFFECTER_PDR);
+    auto inPDRRepo = pldm_pdr_init();
+    auto outPDRRepo = pldm_pdr_init();
+    Repo outRepo(outPDRRepo);
+    Handler handler("./pdr_jsons/state_effecter/good", inPDRRepo);
+    Repo inRepo(inPDRRepo);
+    getRepoByType(inRepo, outRepo, PLDM_STATE_EFFECTER_PDR);
     pdr_utils::PdrEntry e;
-    auto record1 = pdr::getRecordByHandle(pdrRepo, 1, e);
+    auto record1 = pdr::getRecordByHandle(outRepo, 1, e);
     ASSERT_NE(record1, nullptr);
     pldm_state_effecter_pdr* pdr =
         reinterpret_cast<pldm_state_effecter_pdr*>(e.data);
@@ -232,7 +252,6 @@
     stateField.push_back({PLDM_REQUEST_SET, 4});
 
     MockdBusHandler handlerObj;
-    platform::Handler handler;
     auto rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(
         handlerObj, 0x1, stateField);
     ASSERT_EQ(rc, PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE);
@@ -252,4 +271,7 @@
     rc = handler.setStateEffecterStatesHandler<MockdBusHandler>(handlerObj, 0x2,
                                                                 newStateField);
     ASSERT_EQ(rc, PLDM_PLATFORM_INVALID_STATE_VALUE);
+
+    pldm_pdr_destroy(inPDRRepo);
+    pldm_pdr_destroy(outPDRRepo);
 }