Add Serialization Support for Dump Entry Attributes

Implemented serialization of dump entry attributes using the
nlohmann::json library. Added serialization support in the Dump Entry
class, serializing attributes including originatorId, originatorType,
and startTime. These attributes are not part of the dump filename and
thus require serialization to ensure their state is preserved.

Deserialization will occur only if the serialization version matches
and the dump ID in the dump object matches the ID in the
serialized file.

Tests:
- Created BMC dumps and restarted service
- Created BMC dumps and restarted BMC
- Created 200 BMC dumps and restarted service and BMC multiple times

File:
```
{"dumpId":2,"originatorId":"","originatorType":1,"startTime":1718199238942411,"version":1}
```

Change-Id: I16ecb058bddd464c8771bd8d08a50ea1877747ed
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
index 171a26c..1fa0acd 100644
--- a/dump_manager_bmc.cpp
+++ b/dump_manager_bmc.cpp
@@ -17,8 +17,6 @@
 #include <sdeventplus/source/base.hpp>
 
 #include <cmath>
-#include <ctime>
-#include <regex>
 
 namespace phosphor
 {
@@ -171,25 +169,15 @@
 
 void Manager::createEntry(const std::filesystem::path& file)
 {
-    // Dump File Name format obmcdump_ID_EPOCHTIME.EXT
-    static constexpr auto ID_POS = 1;
-    static constexpr auto EPOCHTIME_POS = 2;
-    std::regex file_regex("obmcdump_([0-9]+)_([0-9]+).([a-zA-Z0-9]+)");
-
-    std::smatch match;
-    std::string name = file.filename();
-
-    if (!((std::regex_search(name, match, file_regex)) && (match.size() > 0)))
+    auto dumpDetails = extractDumpDetails(file);
+    if (!dumpDetails)
     {
-        lg2::error("Invalid Dump file name, FILENAME: {FILENAME}", "FILENAME",
-                   file);
+        lg2::error("Failed to extract dump details from file name: {PATH}",
+                   "PATH", file);
         return;
     }
 
-    auto idString = match[ID_POS];
-    uint64_t timestamp = stoull(match[EPOCHTIME_POS]) * 1000 * 1000;
-
-    auto id = stoul(idString);
+    auto [id, timestamp, size] = *dumpDetails;
 
     // If there is an existing entry update it and return.
     auto dumpEntry = entries.find(id);
@@ -223,7 +211,6 @@
             "ERROR", e, "OBJECT_PATH", objPath, "ID", id, "TIMESTAMP",
             timestamp, "SIZE", std::filesystem::file_size(file), "FILENAME",
             file);
-        return;
     }
 }
 
@@ -283,18 +270,33 @@
     {
         auto idStr = p.path().filename().string();
 
-        // Consider only directory's with dump id as name.
+        // Consider only directories with dump id as name.
         // Note: As per design one file per directory.
         if ((std::filesystem::is_directory(p.path())) &&
             std::all_of(idStr.begin(), idStr.end(), ::isdigit))
         {
             lastEntryId = std::max(lastEntryId,
                                    static_cast<uint32_t>(std::stoul(idStr)));
-            auto fileIt = std::filesystem::directory_iterator(p.path());
-            // Create dump entry d-bus object.
-            if (fileIt != std::filesystem::end(fileIt))
+            for (const auto& file :
+                 std::filesystem::directory_iterator(p.path()))
             {
-                createEntry(fileIt->path());
+                // Skip .preserve directory
+                if (file.path().filename() == PRESERVE)
+                {
+                    continue;
+                }
+
+                // Entry Object path.
+                auto objPath = std::filesystem::path(baseEntryPath) / idStr;
+                auto entry = Entry::deserializeEntry(bus, std::stoul(idStr),
+                                                     objPath.string(),
+                                                     file.path(), *this);
+
+                if (entry != nullptr)
+                {
+                    entries.insert(
+                        std::make_pair(entry->getDumpId(), std::move(entry)));
+                }
             }
         }
     }