Make sure directory exists

Handle cases where the persistent data directory might not exist, or
might not be writable (as would be the case in unit tests) by ignoring
the error.

This allows unit tests to fail gracefully

Tested: Unit tests pass when persistent data dir isn't writable.
bmcweb boots and restores file session file normally when manually
restarted.

Change-Id: Idbd5155bed8be20738a85a55f0d4f876344a2439
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/include/persistent_data.hpp b/include/persistent_data.hpp
index 13a43c4..625503a 100644
--- a/include/persistent_data.hpp
+++ b/include/persistent_data.hpp
@@ -6,12 +6,14 @@
 #include "ossl_random.hpp"
 #include "sessions.hpp"
 
+#include <boost/beast/core/file_posix.hpp>
 #include <boost/beast/http/fields.hpp>
 #include <nlohmann/json.hpp>
 
 #include <filesystem>
 #include <fstream>
 #include <random>
+#include <system_error>
 
 namespace persistent_data
 {
@@ -208,14 +210,38 @@
 
     void writeData()
     {
-        std::ofstream persistentFile(filename);
+        std::filesystem::path path(filename);
+        path = path.parent_path();
+        std::error_code ecDir;
+        std::filesystem::create_directories(path, ecDir);
+        if (ecDir)
+        {
+            BMCWEB_LOG_CRITICAL("Can't create persistent folders {}",
+                                ecDir.message());
+            return;
+        }
+        boost::beast::file_posix persistentFile;
+        boost::system::error_code ec;
+        persistentFile.open(filename, boost::beast::file_mode::write, ec);
+        if (ec)
+        {
+            BMCWEB_LOG_CRITICAL("Unable to store persistent data to file {}",
+                                ec.message());
+            return;
+        }
 
         // set the permission of the file to 640
         std::filesystem::perms permission =
             std::filesystem::perms::owner_read |
             std::filesystem::perms::owner_write |
             std::filesystem::perms::group_read;
-        std::filesystem::permissions(filename, permission);
+        std::filesystem::permissions(filename, permission, ec);
+        if (ec)
+        {
+            BMCWEB_LOG_CRITICAL("Failed to set filesystem permissions {}",
+                                ec.message());
+            return;
+        }
         const AuthConfigMethods& c =
             SessionStore::getInstance().getAuthMethodsConfig();
         const auto& eventServiceConfig =
@@ -308,7 +334,13 @@
 
             subscriptions.emplace_back(std::move(subscription));
         }
-        persistentFile << data;
+        std::string out = nlohmann::json(data).dump(
+            -1, ' ', true, nlohmann::json::error_handler_t::replace);
+        persistentFile.write(out.data(), out.size(), ec);
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR("Failed to write file {}", ec.message());
+        }
     }
 
     std::string systemUuid;