Create a DBus notification for each LogEntry
For each log entry, a new FilePath DBus object will be created where
the FilePath.path value is the location of the JSON LogEntry file.
Tested:
Tested with unit tests and locally on a machine.
Signed-off-by: Kasun Athukorala <kasunath@google.com>
Change-Id: I5999826f7b4447bfca88b83c487d7c03a1c84a08
diff --git a/include/rde/external_storer_file.hpp b/include/rde/external_storer_file.hpp
index 3d12dc9..f6a6281 100644
--- a/include/rde/external_storer_file.hpp
+++ b/include/rde/external_storer_file.hpp
@@ -2,6 +2,7 @@
#include "external_storer_interface.hpp"
#include "nlohmann/json.hpp"
+#include "notifier_dbus_handler.hpp"
#include <boost/uuid/uuid_generators.hpp>
@@ -75,21 +76,24 @@
/**
* @brief Constructor for the ExternalStorerFileInterface.
*
+ * @param[in] bus - bus to attach to.
* @param[in] rootPath - root path for creating redfish folders.
* Eg: "/run/bmcweb"
* @param[in] fileHandler - an ExternalStorerFileWriter object. This class
* will take the ownership of this object.
*/
ExternalStorerFileInterface(
- std::string_view rootPath,
+ sdbusplus::bus::bus& bus, std::string_view rootPath,
std::unique_ptr<FileHandlerInterface> fileHandler);
bool publishJson(std::string_view jsonStr) override;
private:
+ sdbusplus::bus::bus& bus;
std::string rootPath;
std::unique_ptr<FileHandlerInterface> fileHandler;
std::string logServiceId;
+ std::unique_ptr<CperFileNotifierHandler> cperNotifier;
boost::uuids::random_generator randomGen;
/**
diff --git a/src/main.cpp b/src/main.cpp
index 0b520a9..e81150a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,6 +10,7 @@
#include <boost/asio.hpp>
#include <boost/endian/conversion.hpp>
+#include <sdbusplus/asio/object_server.hpp>
#include <stdplus/fd/create.hpp>
#include <stdplus/fd/impl.hpp>
#include <stdplus/fd/managed.hpp>
@@ -87,11 +88,16 @@
std::make_shared<BufferImpl>(std::move(pciDataHandler));
// rdeCommandHandler initialization
+ std::shared_ptr<sdbusplus::asio::connection> conn =
+ std::make_shared<sdbusplus::asio::connection>(io);
+ conn->request_name("xyz.openbmc_project.bios_bmc_smm_error_logger");
+ sdbusplus::bus::bus& bus = static_cast<sdbusplus::bus::bus&>(*conn);
+
std::unique_ptr<rde::FileHandlerInterface> fileIface =
std::make_unique<rde::ExternalStorerFileWriter>();
std::unique_ptr<rde::ExternalStorerInterface> exFileIface =
std::make_unique<rde::ExternalStorerFileInterface>(
- "/run/bmcweb", std::move(fileIface));
+ bus, "/run/bmcweb", std::move(fileIface));
std::shared_ptr<rde::RdeCommandHandler> rdeCommandHandler =
std::make_unique<rde::RdeCommandHandler>(std::move(exFileIface));
diff --git a/src/rde/external_storer_file.cpp b/src/rde/external_storer_file.cpp
index 0768134..97f2b10 100644
--- a/src/rde/external_storer_file.cpp
+++ b/src/rde/external_storer_file.cpp
@@ -44,10 +44,11 @@
}
ExternalStorerFileInterface::ExternalStorerFileInterface(
- std::string_view rootPath,
+ sdbusplus::bus::bus& bus, std::string_view rootPath,
std::unique_ptr<FileHandlerInterface> fileHandler) :
- rootPath(rootPath),
- fileHandler(std::move(fileHandler)), logServiceId("")
+ bus(bus),
+ rootPath(rootPath), fileHandler(std::move(fileHandler)), logServiceId(""),
+ cperNotifier(std::make_unique<CperFileNotifierHandler>(bus))
{}
bool ExternalStorerFileInterface::publishJson(std::string_view jsonStr)
@@ -115,8 +116,9 @@
}
std::string id = boost::uuids::to_string(randomGen());
- std::string path = "/redfish/v1/Systems/system/LogServices/" +
- logServiceId + "/Entries/" + id;
+ std::string fullPath =
+ fmt::format("{}/redfish/v1/Systems/system/LogServices/{}/Entries/{}",
+ rootPath, logServiceId, id);
// Populate the "Id" with the UUID we generated.
logEntry["Id"] = id;
@@ -124,7 +126,15 @@
// a client.
logEntry.erase("@odata.id");
- return createFile(path, logEntry);
+ if (!fileHandler->createFile(fullPath, logEntry))
+ {
+ fmt::print(stderr, "Failed to create a file for log entry path: {}\n",
+ fullPath);
+ return false;
+ }
+
+ cperNotifier->createEntry(fullPath + "/index.json");
+ return true;
}
bool ExternalStorerFileInterface::processLogService(
diff --git a/test/external_storer_file_test.cpp b/test/external_storer_file_test.cpp
index fc550ee..f2718aa 100644
--- a/test/external_storer_file_test.cpp
+++ b/test/external_storer_file_test.cpp
@@ -1,5 +1,8 @@
#include "rde/external_storer_file.hpp"
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/test/sdbus_mock.hpp>
+
#include <string_view>
#include <gmock/gmock-matchers.h>
@@ -15,6 +18,7 @@
using ::testing::DoAll;
using ::testing::Return;
using ::testing::SaveArg;
+using ::testing::StrEq;
class MockFileWriter : public FileHandlerInterface
{
@@ -30,14 +34,26 @@
{
public:
ExternalStorerFileTest() :
+ bus(sdbusplus::get_mocked_new(&sdbusMock)),
mockFileWriter(std::make_unique<MockFileWriter>())
{
mockFileWriterPtr = dynamic_cast<MockFileWriter*>(mockFileWriter.get());
+
+ EXPECT_CALL(
+ sdbusMock,
+ sd_bus_add_object_manager(
+ nullptr, _,
+ StrEq(
+ "/xyz/openbmc_project/external_storer/bios_bmc_smm_error_logger/CPER")))
+ .WillOnce(Return(0));
+
exStorer = std::make_unique<ExternalStorerFileInterface>(
- rootPath, std::move(mockFileWriter));
+ bus, rootPath, std::move(mockFileWriter));
}
protected:
+ sdbusplus::SdBusMock sdbusMock;
+ sdbusplus::bus::bus bus;
std::unique_ptr<FileHandlerInterface> mockFileWriter;
std::unique_ptr<ExternalStorerFileInterface> exStorer;
MockFileWriter* mockFileWriterPtr;
@@ -147,12 +163,29 @@
"@odata.type": "#LogEntry.v1_13_0.LogEntry"
}
)";
+
nlohmann::json logEntryOut;
EXPECT_CALL(*mockFileWriterPtr, createFile(_, _))
.WillOnce(DoAll(SaveArg<1>(&logEntryOut), Return(true)));
+
+ constexpr const char* dbusPath =
+ "/xyz/openbmc_project/external_storer/bios_bmc_smm_error_logger/CPER/entry0";
+ constexpr const char* dbusInterface = "xyz.openbmc_project.Common.FilePath";
+
+ EXPECT_CALL(sdbusMock, sd_bus_add_object_vtable(nullptr, _, StrEq(dbusPath),
+ StrEq(dbusInterface), _, _))
+ .WillOnce(Return(0));
+ EXPECT_CALL(sdbusMock,
+ sd_bus_emit_interfaces_added_strv(nullptr, StrEq(dbusPath), _))
+ .WillOnce(Return(0));
+
EXPECT_THAT(exStorer->publishJson(jsonLogEntry), true);
EXPECT_NE(logEntryOut["Id"], nullptr);
EXPECT_EQ(logEntryOut["@odata.id"], nullptr);
+
+ EXPECT_CALL(sdbusMock, sd_bus_emit_interfaces_removed_strv(
+ nullptr, StrEq(dbusPath), _))
+ .WillOnce(Return(0));
}
TEST_F(ExternalStorerFileTest, OtherSchemaNoOdataIdTest)