From e2fe46b50a9183618b2be9ce17d5824639556ebb Mon Sep 17 00:00:00 2001 From: Sangwan Kwon Date: Thu, 13 Jun 2019 08:47:23 +0900 Subject: [PATCH] Apply meyer's singleton to programming interface - Re-design API more simply Signed-off-by: Sangwan Kwon --- include/osquery/manager.h | 26 ++++++++++++++------------ interface-draft.md | 18 ++++++------------ osquery/manager/manager.cpp | 29 +++++++++++++++++++++++------ osquery/manager/manager_tests.cpp | 15 +++------------ 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/osquery/manager.h b/include/osquery/manager.h index f691da8..b46ae5b 100644 --- a/include/osquery/manager.h +++ b/include/osquery/manager.h @@ -36,22 +36,24 @@ using Rows = std::vector; class OsqueryManager final { public: - ~OsqueryManager(void) noexcept; + OsqueryManager(const OsqueryManager&) = delete; + OsqueryManager& operator=(const OsqueryManager&) = delete; - OsqueryManager(const OsqueryManager &) = delete; - OsqueryManager(OsqueryManager &&) = delete; - OsqueryManager &operator=(const OsqueryManager &) = delete; - OsqueryManager &operator=(OsqueryManager &&) = delete; - - static std::shared_ptr Load(); - - Rows execute(const std::string& query) const; - - std::vector tables(void) const noexcept; - std::vector columns(const std::string& table) const noexcept; + /// TBD: Consider error handling. + static Rows execute(const std::string& query); + static std::vector tables(void) noexcept; + static std::vector columns(const std::string& table) noexcept; private: OsqueryManager(); + ~OsqueryManager() noexcept; + + static OsqueryManager& instance(); + + /// TODO(Sangwan): Apply pimpl idiom. + Rows executeInternal(const std::string& query) const; + std::vector tablesInternal(void) const noexcept; + std::vector columnsInternal(const std::string& table) const noexcept; }; } // namespace osquery diff --git a/interface-draft.md b/interface-draft.md index ba50497..3700115 100644 --- a/interface-draft.md +++ b/interface-draft.md @@ -19,13 +19,10 @@ // 1. Write query as std::string std::string query = "SELECT subject_label, object_label FROM smack WHERE access_type = 'read'"; - // 2. Load OsqueryManager - auto manager = OsqueryManager::Load(); + // 2. Execute query by using OsqueryManager + auto rows = OsqueryManager::execute(query); - // 3. Execute query by using OsqueryManager - auto rows = manager->execute(query); - - // 4. Get result + // 3. Get result for (const auto& row : rows) { std::string slabel = row["subject_label"]; std::string olabel = row["object_label]; @@ -51,7 +48,7 @@ using namespace osquerypp; // 1. Write callback function - auto onDeny = [&](const EventContext& ec, const Row& row) + auto onDeny = [&](const EventContext& ec, const Row& row) { // get data of event table std::cout << row["action"] << std::endl; @@ -60,9 +57,6 @@ std::cout << row["object_label"] << std::endl; } - // 2. Load OsqueryManager - auto manager = OsqueryManager::Load(); - - // 3. Register callback with event_table by using OsqueryManager - manager->subscribe("smack_deny_events", onDeny); + // 2. Register callback with event_table by using OsqueryManager + OsqueryManager::subscribe("smack_deny_events", onDeny); ``` diff --git a/osquery/manager/manager.cpp b/osquery/manager/manager.cpp index 592dbf8..7524fad 100644 --- a/osquery/manager/manager.cpp +++ b/osquery/manager/manager.cpp @@ -41,7 +41,7 @@ OsqueryManager::OsqueryManager() if (!logDir.empty() && !(pathExists(logDir).ok())) boost::filesystem::create_directories(logDir); - // TODO(sangwan.kwon): Get debug mode at build time + // TODO(Sangwan): Get debug mode at build time Flag::updateValue("verbose_debug", "true"); const char* cargv[] = {"tizen-osquery"}; @@ -56,13 +56,20 @@ OsqueryManager::~OsqueryManager(void) noexcept osquery::shutdownOsquery(); } -std::shared_ptr OsqueryManager::Load() +OsqueryManager& OsqueryManager::instance() { - static std::shared_ptr manager(new OsqueryManager); + static OsqueryManager manager; return manager; } -Rows OsqueryManager::execute(const std::string& query) const +Rows OsqueryManager::execute(const std::string& query) +{ + LOG(INFO) << "Execute query: " << query; + + return instance().executeInternal(query); +} + +Rows OsqueryManager::executeInternal(const std::string& query) const { LOG(INFO) << "Execute query: " << query; @@ -74,12 +81,22 @@ Rows OsqueryManager::execute(const std::string& query) const return results; } -std::vector OsqueryManager::tables(void) const noexcept +std::vector OsqueryManager::tables(void) noexcept +{ + return instance().tablesInternal(); +} + +std::vector OsqueryManager::columns(const std::string& table) noexcept +{ + return instance().columnsInternal(table); +} + +std::vector OsqueryManager::tablesInternal(void) const noexcept { return SQL::getTableNames(); } -std::vector OsqueryManager::columns(const std::string& table) const noexcept +std::vector OsqueryManager::columnsInternal(const std::string& table) const noexcept { std::stringstream query; query << "SELECT * FROM " << table; diff --git a/osquery/manager/manager_tests.cpp b/osquery/manager/manager_tests.cpp index 6f308a7..b52b63b 100644 --- a/osquery/manager/manager_tests.cpp +++ b/osquery/manager/manager_tests.cpp @@ -23,16 +23,9 @@ using namespace osquery; class ManagerTests : public testing::Test {}; -TEST_F(ManagerTests, test_manager_load) { - auto manager = OsqueryManager::Load(); - EXPECT_TRUE(manager != nullptr); -} - TEST_F(ManagerTests, test_manager_execute) { - auto manager = OsqueryManager::Load(); - std::string query = "SELECT * FROM time"; - auto rows = manager->execute(query); + auto rows = OsqueryManager::execute(query); EXPECT_EQ(rows.size(), 1); VLOG(1) << "[Test] time table rows:"; @@ -42,8 +35,7 @@ TEST_F(ManagerTests, test_manager_execute) { } TEST_F(ManagerTests, test_manager_tables) { - auto manager = OsqueryManager::Load(); - auto tables = manager->tables(); + auto tables = OsqueryManager::tables(); EXPECT_TRUE(tables.size() > 0); VLOG(1) << "[Test] Enabled tables:"; @@ -52,8 +44,7 @@ TEST_F(ManagerTests, test_manager_tables) { } TEST_F(ManagerTests, test_manager_columns) { - auto manager = OsqueryManager::Load(); - auto columns = manager->columns("time"); + auto columns = OsqueryManager::columns("time"); EXPECT_TRUE(columns.size() > 0); VLOG(1) << "[Test] Enabled columns of time table:"; -- 2.7.4