Refactor virtual table 37/239337/1
authorSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 24 Jul 2020 04:38:25 +0000 (13:38 +0900)
committerSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 24 Jul 2020 05:07:28 +0000 (14:07 +0900)
Change-Id: If7d0fa01547a3734254fc89b981c9ff00ae59ba3
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
19 files changed:
src/osquery/core/tables.cpp
src/osquery/include/osquery/tables.h
src/osquery/sql/tests/sql.cpp
src/osquery/sql/tests/virtual_table.cpp
src/osquery/sql/virtual_table.cpp
src/vist/table/CMakeLists.txt
src/vist/table/builder.hpp [new file with mode: 0644]
src/vist/table/dynamic-table.hpp
src/vist/table/parser.hpp [new file with mode: 0644]
src/vist/table/policy/bluetooth/table.cpp
src/vist/table/policy/bluetooth/table.hpp
src/vist/table/policy/policy-admin.cpp
src/vist/table/policy/policy-admin.hpp
src/vist/table/policy/policy.cpp
src/vist/table/policy/policy.hpp
src/vist/table/policy/sample/table.cpp
src/vist/table/policy/sample/table.hpp
src/vist/table/util.cpp [new file with mode: 0644]
src/vist/table/util.hpp [new file with mode: 0644]

index 48ced6c..18bfa80 100644 (file)
@@ -138,8 +138,7 @@ Status TablePlugin::call(const PluginRequest& request,
 
        if (action == "generate") {
                auto context = getContextFromRequest(request);
-               TableRows result = generate(context);
-               response = tableRowsToPluginResponse(result);
+               response = generate(context);
        } else if (action == "delete") {
                auto context = getContextFromRequest(request);
                response = delete_(context, request);
index 091cb65..5cf05da 100644 (file)
@@ -748,10 +748,9 @@ public:
         * @param context A query context filled in by SQLite's virtual table API.
         * @return The result rows for this table, given the query context.
         */
-       virtual TableRows generate(QueryContext& context)
+       virtual QueryData generate(QueryContext&)
        {
-               (void)context;
-               return TableRows();
+               return QueryData();
        }
 
        /// Callback for DELETE statements
index c520c45..9543bf0 100644 (file)
@@ -37,20 +37,18 @@ private:
                };
        }
 
-       TableRows generate(QueryContext& ctx)
+       QueryData generate(QueryContext& ctx)
        {
-               TableRows results;
+               QueryData results;
                if (ctx.constraints["test_int"].existsAndMatches("1")) {
-                       results.push_back(
-                       make_table_row({{"test_int", "1"}, {"test_text", "0"}}));
+                       results.push_back({{"test_int", "1"}, {"test_text", "0"}});
                } else {
-                       results.push_back(
-                       make_table_row({{"test_int", "0"}, {"test_text", "1"}}));
+                       results.push_back({{"test_int", "0"}, {"test_text", "1"}});
                }
 
                auto ints = ctx.constraints["test_int"].getAll<int>(EQUALS);
                for (const auto& int_match : ints) {
-                       results.push_back(make_table_row({{"test_int", INTEGER(int_match)}}));
+                       results.push_back({{"test_int", INTEGER(int_match)}});
                }
 
                return results;
index f7cef0d..bec6d6c 100644 (file)
@@ -225,11 +225,11 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext&) override
+       QueryData generate(QueryContext&) override
        {
-               TableRows tr;
-               tr.push_back(make_table_row({{"x", "1"}, {"y", "2"}}));
-               tr.push_back(make_table_row({{"x", "2"}, {"y", "1"}}));
+               QueryData tr;
+               tr.push_back({{"x", "1"}, {"y", "2"}});
+               tr.push_back({{"x", "2"}, {"y", "1"}});
                return tr;
        }
 
@@ -248,11 +248,11 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext&) override
+       QueryData generate(QueryContext&) override
        {
-               TableRows tr;
-               tr.push_back(make_table_row({{"x", "1"}, {"z", "2"}}));
-               tr.push_back(make_table_row({{"x", "2"}, {"z", "1"}}));
+               QueryData tr;
+               tr.push_back({{"x", "1"}, {"z", "2"}});
+               tr.push_back({{"x", "2"}, {"z", "1"}});
                return tr;
        }
 
@@ -353,10 +353,10 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext&) override
+       QueryData generate(QueryContext&) override
        {
-               TableRows results;
-               results.push_back(make_table_row({{"data", "{\"test\": 1}"}}));
+               QueryData results;
+               results.push_back({{"data", "{\"test\": 1}"}});
                return results;
        }
 
@@ -431,16 +431,14 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
-               TableRows results;
+               QueryData results;
                if (context.isCached("awesome_data")) {
                        // There is cache entry for awesome data.
-                       results.push_back(make_table_row({{"data", "more_awesome_data"}}));
+                       results.push_back({{"data", "more_awesome_data"}});
                } else {
-                       auto tr = make_table_row({{"data", "awesome_data"}});
-                       context.setCache("awesome_data", static_cast < TableRowHolder && >(tr));
-                       results.push_back(std::move(tr));
+                       results.push_back({{"data", "awesome_data"}});
                }
                return results;
        }
@@ -490,18 +488,13 @@ public:
                return TableAttributes::CACHEABLE;
        }
 
-       TableRows generate(QueryContext& ctx) override
+       QueryData generate(QueryContext& ctx) override
        {
-               if (isCached(60, ctx)) {
-                       return getCache();
-               }
-
                generates_++;
-               auto r = make_table_row();
+               Row r;
                r["i"] = "1";
-               TableRows result;
+               QueryData result;
                result.push_back(std::move(r));
-               setCache(60, 1, ctx, result);
                return result;
        }
 
@@ -574,15 +567,15 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
-               TableRows results;
+               QueryData results;
 
                // To test, we'll move all predicate constraints into the result set.
                // First we'll move constrains for the column `i` using operands =, LIKE.
                auto i = context.constraints["i"].getAll(EQUALS);
                for (const auto& constraint : i) {
-                       auto r = make_table_row();
+                       Row r;
                        r["i"] = constraint;
                        r["op"] = "EQUALS";
                        results.push_back(std::move(r));
@@ -590,7 +583,7 @@ public:
 
                i = context.constraints["i"].getAll(LIKE);
                for (const auto& constraint : i) {
-                       auto r = make_table_row();
+                       Row r;
                        r["i"] = constraint;
                        r["op"] = "LIKE";
                        results.push_back(std::move(r));
@@ -685,20 +678,20 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
                scans++;
 
-               TableRows results;
+               QueryData results;
                auto indexes = context.constraints["i"].getAll<int>(EQUALS);
                for (const auto& i : indexes) {
-                       results.push_back(make_table_row(
-                       {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "none"}}));
+                       results.push_back(
+                       {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "none"}});
                }
                if (indexes.empty()) {
                        for (size_t i = 0; i < 100; i++) {
-                               results.push_back(make_table_row(
-                               {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "some"}}));
+                               results.push_back(
+                               {{"i", INTEGER(i)}, {"j", INTEGER(i * 10)}, {"text", "some"}});
                        }
                }
                return results;
@@ -719,19 +712,19 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
                scans++;
 
-               TableRows results;
+               QueryData results;
                auto indexes = context.constraints["j"].getAll<int>(EQUALS);
                for (const auto& j : indexes) {
-                       results.push_back(make_table_row({{"j", INTEGER(j)}, {"text", "none"}}));
+                       results.push_back({{"j", INTEGER(j)}, {"text", "none"}});
                }
                if (indexes.empty()) {
                        for (size_t j = 0; j < 100; j++) {
                                results.push_back(
-                               make_table_row({{"j", INTEGER(j)}, {"text", "some"}}));
+                               {{"j", INTEGER(j)}, {"text", "some"}});
                        }
                }
                return results;
@@ -752,13 +745,13 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
                scans++;
 
-               TableRows results;
+               QueryData results;
                for (size_t i = 0; i < 10; i++) {
-                       results.push_back(make_table_row({{"i", INTEGER(i)}, {"text", "some"}}));
+                       results.push_back({{"i", INTEGER(i)}, {"text", "some"}});
                }
                return results;
        }
@@ -786,9 +779,9 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
-               auto r = make_table_row();
+               Row r;
                if (context.isColumnUsed("col1")) {
                        r["col1"] = "value1";
                }
@@ -798,7 +791,7 @@ public:
                if (context.isColumnUsed("col3")) {
                        r["col3"] = "value3";
                }
-               TableRows result;
+               QueryData result;
                result.push_back(std::move(r));
                return result;
        }
@@ -868,10 +861,10 @@ private:
        }
 
 public:
-       TableRows generate(QueryContext& context) override
+       QueryData generate(QueryContext& context) override
        {
-               TableRows results;
-               auto r = make_table_row();
+               QueryData results;
+               Row r;
                if (context.isAnyColumnUsed(UsedColumnsBitset(0x1))) {
                        r["col1"] = "value1";
                }
index 9221842..511d2d7 100644 (file)
@@ -923,7 +923,7 @@ static int xFilter(sqlite3_vtab_cursor* pVtabCursor,
        if (Registry::get().exists("table", pVtab->content->name, true)) {
                auto plugin = Registry::get().plugin("table", pVtab->content->name);
                auto table = std::dynamic_pointer_cast<TablePlugin>(plugin);
-               pCur->rows = table->generate(context);
+               pCur->rows = tableRowsFromQueryData(table->generate(context));
        } else {
                PluginRequest request = {{"action", "generate"}};
                TablePlugin::setRequestFromContext(context, request);
index aefd1ef..e17acc0 100644 (file)
@@ -13,7 +13,8 @@
 #  limitations under the License
 
 ## static virtual table
-ADD_VIST_LIBRARY(vist_table policy/policy-admin.cpp
+ADD_VIST_LIBRARY(vist_table util.cpp
+                                                       policy/policy-admin.cpp
                                                        policy/policy.cpp)
 
 ## dynamic virtual table
diff --git a/src/vist/table/builder.hpp b/src/vist/table/builder.hpp
new file mode 100644 (file)
index 0000000..f3e70a8
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <vist/exception.hpp>
+
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
+
+#include <osquery/registry.h>
+#include <osquery/sql/dynamic_table_row.h>
+#include <osquery/tables.h>
+
+using namespace osquery;
+
+namespace vist {
+namespace table {
+
+template<class T> struct dependent_false : std::false_type {};
+
+struct Builder {
+       template <typename T>
+       static void table(const std::string& name)
+       {
+               // Register virtual table to sqlite3
+               auto tables = RegistryFactory::get().registry("table");
+               tables->add(name, std::make_shared<T>());
+       }
+
+       template <typename T>
+       static std::tuple<std::string, ColumnType, ColumnOptions> column(const std::string& name)
+       {
+               if constexpr(std::is_same_v<T, int>)
+                       return std::tuple(name, INTEGER_TYPE, ColumnOptions::DEFAULT);
+               else if constexpr(std::is_same_v<T, std::string>)
+                       return std::tuple(name, TEXT_TYPE, ColumnOptions::DEFAULT);
+               else
+                       static_assert(dependent_false<T>::value, "Not supported column type.");
+       }
+};
+
+} // namespace table
+} // namespace vist
index 7b82781..dbe6d1e 100644 (file)
  *  limitations under the License
  */
 
-#include <memory>
+#pragma once
 
-#include <osquery/registry.h>
-#include <osquery/sql/dynamic_table_row.h>
 #include <osquery/tables.h>
 
 using namespace osquery;
@@ -30,14 +28,6 @@ public:
        using FactoryType = DynamicTable* (*)();
 
        virtual void init() = 0;
-
-       template <typename T>
-       static void Register(const std::string& name, std::shared_ptr<T>&& table)
-       {
-               // Register virtual table to sqlite3
-               auto tables = RegistryFactory::get().registry("table");
-               tables->add(name, std::move(table));
-       }
 };
 
 } // namespace table
diff --git a/src/vist/table/parser.hpp b/src/vist/table/parser.hpp
new file mode 100644 (file)
index 0000000..0c8f08f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <vist/exception.hpp>
+#include <vist/json.hpp>
+
+#include <osquery/tables.h>
+
+using namespace osquery;
+
+namespace vist {
+namespace table {
+
+struct Parser {
+
+       template <typename T>
+       static auto column(const PluginRequest& request, std::size_t index) -> T
+       {
+               if (request.count("json_values") == 0)
+                       THROW(ErrCode::LogicError) << "Wrong request format. Not found json value.";
+
+               json::Json document = json::Json::Parse(request.at("json_values"));
+               json::Array values = document.get<json::Array>("values");
+               if (values.size() < index)
+                       THROW(ErrCode::LogicError) << "Wrong index.";
+
+               return static_cast<T>(values.at(index));
+       }
+
+};
+
+} // namespace table
+} // namespace vist
index 4af0a16..ade0c1a 100644 (file)
 #include "table.hpp"
 
 #include <vist/exception.hpp>
-#include <vist/json.hpp>
 #include <vist/logger.hpp>
 #include <vist/policy/api.hpp>
+#include <vist/table/builder.hpp>
+#include <vist/table/parser.hpp>
+#include <vist/table/util.hpp>
 
 extern "C" vist::table::DynamicTable* DynamicTableFactory()
 {
@@ -48,7 +50,7 @@ void setPolicy(const std::string& name, int value)
 
 void BluetoothTable::init()
 {
-       DynamicTable::Register("bluetooth", std::make_shared<BluetoothTable>());
+       Builder::table<BluetoothTable>("bluetooth");
 
        auto provider = std::make_shared<policy::Bluetooth>("bluetooth");
        provider->add(std::make_shared<policy::BluetoothState>());
@@ -64,15 +66,17 @@ void BluetoothTable::init()
 TableColumns BluetoothTable::columns() const
 {
        return {
-               std::make_tuple("state", INTEGER_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("desktopConnectivity", INTEGER_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("pairing", INTEGER_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("tethering", INTEGER_TYPE, ColumnOptions::DEFAULT),
+               Builder::column<int>("state"),
+               Builder::column<int>("desktopConnectivity"),
+               Builder::column<int>("pairing"),
+               Builder::column<int>("tethering")
        };
 }
 
-TableRows BluetoothTable::generate(QueryContext&) try
+QueryData BluetoothTable::generate(QueryContext&)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Select query about bluetooth table.";
 
        Row row;
@@ -84,50 +88,26 @@ TableRows BluetoothTable::generate(QueryContext&) try
        QueryData results;
        results.emplace_back(std::move(row));
 
-       return osquery::tableRowsFromQueryData(std::move(results));
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
+       return results;
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request) try
+QueryData BluetoothTable::update(QueryContext&, const PluginRequest& request)
 {
-       INFO(VIST) << "Update query about bluetooth table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
+       TABLE_EXCEPTION_GUARD_START
 
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       json::Json document = json::Json::Parse(request.at("json_values"));
-       json::Array values = document.get<json::Array>("values");
-       if (values.size() != 4)
-               throw std::runtime_error("Wrong request format.");
+       INFO(VIST) << "Update query about bluetooth table.";
 
        /// TODO(Sangwan): Sync vtab schema with policy definition
-       setPolicy("bluetooth", static_cast<int>(values.at(0)));
-       setPolicy("bluetooth-desktop-connectivity", static_cast<int>(values.at(1)));
-       setPolicy("bluetooth-pairing", static_cast<int>(values.at(2)));
-       setPolicy("bluetooth-tethering", static_cast<int>(values.at(3)));
-
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+       setPolicy("bluetooth", Parser::column<int>(request, 0));
+       setPolicy("bluetooth-desktop-connectivity", Parser::column<int>(request, 1));
+       setPolicy("bluetooth-pairing", Parser::column<int>(request, 2));
+       setPolicy("bluetooth-tethering", Parser::column<int>(request, 3));
+
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
 } // namespace table
index 67996b0..5695f14 100644 (file)
@@ -31,7 +31,7 @@ public:
 
 private:
        TableColumns columns() const override;
-       TableRows generate(QueryContext&) override;
+       QueryData generate(QueryContext&) override;
        QueryData update(QueryContext&, const PluginRequest& request) override;
 };
 
index 9edc0d0..3f7b705 100644 (file)
 #include "policy-admin.hpp"
 
 #include <vist/exception.hpp>
-#include <vist/json.hpp>
 #include <vist/logger.hpp>
 #include <vist/policy/api.hpp>
-
-#include <osquery/registry.h>
-#include <osquery/sql/dynamic_table_row.h>
-
-#include <memory>
-#include <stdexcept>
-#include <string>
+#include <vist/table/builder.hpp>
+#include <vist/table/parser.hpp>
+#include <vist/table/util.hpp>
 
 namespace vist {
 namespace table {
 
 namespace {
 
-std::string getValue(std::string&& alias, const std::string& key)
+std::string removeAlias(std::string&& alias)
 {
        auto pos = alias.find(";");
        auto token = alias.substr(0, pos);
 
-       if (token == key)
+       if (token == "name")
                return alias.erase(0, pos + 1);
        else
                return std::string();
 }
 
-std::string parseAdmin(const std::string& request, bool insert = true)
-{
-       json::Json document = json::Json::Parse(request);
-       json::Array values = document.get<json::Array>("values");
-
-       if (insert)
-               return values.at(0);
-       else
-               return getValue(values.at(0), "name");
-}
-
 } // anonymous namespace
 
 void PolicyAdminTable::Init()
 {
-       auto tables = RegistryFactory::get().registry("table");
-       tables->add("policy_admin", std::make_shared<PolicyAdminTable>());
+       Builder::table<PolicyAdminTable>("policy_admin");
 }
 
 TableColumns PolicyAdminTable::columns() const
 {
        return {
-               std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("activated", INTEGER_TYPE, ColumnOptions::DEFAULT),
+               Builder::column<std::string>("name"),
+               Builder::column<int>("activated"),
        };
 }
 
-TableRows PolicyAdminTable::generate(QueryContext& context) try
+QueryData PolicyAdminTable::generate(QueryContext& context)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Select query about policy-admin table.";
 
        QueryData results;
@@ -104,101 +89,55 @@ TableRows PolicyAdminTable::generate(QueryContext& context) try
                }
        }
 
-       return osquery::tableRowsFromQueryData(std::move(results));
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
+       return results;
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request) try
+QueryData PolicyAdminTable::insert(QueryContext&, const PluginRequest& request)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Insert query about policy-admin table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
+       auto admin = Parser::column<std::string>(request, 0);
 
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       auto admin = parseAdmin(request.at("json_values"));
        DEBUG(VIST) << "Admin info [name]: " << admin;
        vist::policy::API::Admin::Enroll(admin);
 
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request) try
+QueryData PolicyAdminTable::delete_(QueryContext&, const PluginRequest& request)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Delete query about policy-admin table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
+       auto admin = removeAlias(Parser::column<std::string>(request, 0));
 
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       auto admin = parseAdmin(request.at("json_values"), false);
        DEBUG(VIST) << "Admin info [name]: " << admin;
        vist::policy::API::Admin::Disenroll(admin);
 
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request) try
+QueryData PolicyAdminTable::update(QueryContext&, const PluginRequest& request)
 {
-       INFO(VIST) << "Update query about policy-admin table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
+       TABLE_EXCEPTION_GUARD_START
 
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       json::Json document = json::Json::Parse(request.at("json_values"));
-       json::Array values = document.get<json::Array>("values");
-       if (values.size() != 2)
-               throw std::runtime_error("Wrong request format.");
+       INFO(VIST) << "Update query about policy-admin table.";
 
-       std::string name = static_cast<std::string>(values.at(0));
-       int activated = static_cast<int>(values.at(1));
+       auto name = Parser::column<std::string>(request, 0);
+       auto activated = Parser::column<int>(request, 1);
 
        vist::policy::API::Admin::Activate(name, activated);
 
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
 } // namespace tables
index d8a8a7e..ff701e5 100644 (file)
@@ -27,7 +27,7 @@ public:
 
 private:
        TableColumns columns() const override;
-       TableRows generate(QueryContext&) override;
+       QueryData generate(QueryContext&) override;
        QueryData delete_(QueryContext&, const PluginRequest& request) override;
        QueryData insert(QueryContext&, const PluginRequest& request) override;
        QueryData update(QueryContext&, const PluginRequest& request) override;
index ca0060b..849bb09 100644 (file)
 #include "policy.hpp"
 
 #include <vist/exception.hpp>
-#include <vist/json.hpp>
 #include <vist/logger.hpp>
 #include <vist/policy/api.hpp>
-
-#include <osquery/registry.h>
-#include <osquery/sql/dynamic_table_row.h>
+#include <vist/table/builder.hpp>
+#include <vist/table/parser.hpp>
+#include <vist/table/util.hpp>
 
 #include <memory>
 #include <stdexcept>
@@ -46,20 +45,21 @@ Row convert(const std::string& name, const vist::policy::PolicyValue& value)
 
 void PolicyTable::Init()
 {
-       auto tables = RegistryFactory::get().registry("table");
-       tables->add("policy", std::make_shared<PolicyTable>());
+       Builder::table<PolicyTable>("policy");
 }
 
 TableColumns PolicyTable::columns() const
 {
        return {
-               std::make_tuple("name", TEXT_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("value", TEXT_TYPE, ColumnOptions::DEFAULT),
+               Builder::column<std::string>("name"),
+               Builder::column<std::string>("value")
        };
 }
 
-TableRows PolicyTable::generate(QueryContext& context) try
+QueryData PolicyTable::generate(QueryContext& context)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Select query about policy table.";
 
        QueryData results;
@@ -80,49 +80,25 @@ TableRows PolicyTable::generate(QueryContext& context) try
                }
        }
 
-       return osquery::tableRowsFromQueryData(std::move(results));
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
+       return results;
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData PolicyTable::update(QueryContext&, const PluginRequest& request) try
+QueryData PolicyTable::update(QueryContext&, const PluginRequest& request)
 {
-       INFO(VIST) << "Update query about policy table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
+       TABLE_EXCEPTION_GUARD_START
 
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       json::Json document = json::Json::Parse(request.at("json_values"));
-       json::Array values = document.get<json::Array>("values");
-       if (values.size() != 2)
-               throw std::runtime_error("Wrong request format.");
+       INFO(VIST) << "Update query about policy table.";
 
-       std::string name = static_cast<std::string>(values.at(0));
-       std::string dumpedValue = static_cast<std::string>(values.at(1));
+       auto name = Parser::column<std::string>(request, 0);
+       auto dumpedValue = Parser::column<std::string>(request, 1);
 
        vist::policy::API::Admin::Set(name, vist::policy::PolicyValue(dumpedValue, true));
 
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
 } // namespace table
index f96c473..5ef6f71 100644 (file)
@@ -27,7 +27,7 @@ public:
 
 private:
        TableColumns columns() const override;
-       TableRows generate(QueryContext&) override;
+       QueryData generate(QueryContext&) override;
        QueryData update(QueryContext&, const PluginRequest& request) override;
 };
 
index 3fc8019..487d9f9 100644 (file)
 #include "table.hpp"
 
 #include <vist/exception.hpp>
-#include <vist/json.hpp>
 #include <vist/logger.hpp>
 #include <vist/policy/api.hpp>
+#include <vist/table/builder.hpp>
+#include <vist/table/parser.hpp>
+#include <vist/table/util.hpp>
 
 extern "C" vist::table::DynamicTable* DynamicTableFactory()
 {
@@ -32,7 +34,7 @@ namespace table {
 
 void SamplePolicyTable::init()
 {
-       DynamicTable::Register("sample_policy", std::make_shared<SamplePolicyTable>());
+       Builder::table<SamplePolicyTable>("sample_policy");
 
        // Register policy to policy-manager
        using namespace policy;
@@ -48,13 +50,15 @@ void SamplePolicyTable::init()
 TableColumns SamplePolicyTable::columns() const
 {
        return {
-               std::make_tuple("sample_int_policy", INTEGER_TYPE, ColumnOptions::DEFAULT),
-               std::make_tuple("sample_str_policy", TEXT_TYPE, ColumnOptions::DEFAULT),
+               Builder::column<int>("sample_int_policy"),
+               Builder::column<std::string>("sample_str_policy")
        };
 }
 
-TableRows SamplePolicyTable::generate(QueryContext&) try
+QueryData SamplePolicyTable::generate(QueryContext&)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Select query about sample-policy table.";
 
        Row row;
@@ -67,49 +71,26 @@ TableRows SamplePolicyTable::generate(QueryContext&) try
        QueryData results;
        results.emplace_back(std::move(row));
 
-       return osquery::tableRowsFromQueryData(std::move(results));
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return osquery::tableRowsFromQueryData({ r });
+       return results;
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
-QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request) try
+QueryData SamplePolicyTable::update(QueryContext&, const PluginRequest& request)
 {
+       TABLE_EXCEPTION_GUARD_START
+
        INFO(VIST) << "Update query about sample-policy table.";
-       if (request.count("json_values") == 0)
-               throw std::runtime_error("Wrong request format. Not found json value.");
-
-       DEBUG(VIST) << "Request values: " << request.at("json_values");
-       json::Json document = json::Json::Parse(request.at("json_values"));
-       json::Array values = document.get<json::Array>("values");
-       if (values.size() != 2)
-               throw std::runtime_error("Wrong request format.");
-
-       policy::API::Admin::Set("sample_int_policy",
-                       policy::PolicyValue(static_cast<int>(values.at(0))));
-       policy::API::Admin::Set("sample_str_policy",
-                       policy::PolicyValue(static_cast<std::string>(values.at(1))));
-
-       Row r;
-       r["status"] = "success";
-       return { r };
-} catch (const vist::Exception<ErrCode>& e)
-{
-       ERROR(VIST) << "Failed to query: " << e.what();
-       Row r;
-       return { r };
-} catch (...)
-{
-       ERROR(VIST) << "Failed to query with unknown exception.";
-       Row r;
-       return { r };
+
+       auto intPolicy = Parser::column<int>(request, 0);
+       auto strPolicy = Parser::column<std::string>(request, 1);
+
+       policy::API::Admin::Set("sample_int_policy", policy::PolicyValue(intPolicy));
+       policy::API::Admin::Set("sample_str_policy", policy::PolicyValue(strPolicy));
+
+       return success();
+
+       TABLE_EXCEPTION_GUARD_END
 }
 
 } // namespace table
index ff80992..1934e9b 100644 (file)
@@ -32,7 +32,7 @@ public:
 
 private:
        TableColumns columns() const override;
-       TableRows generate(QueryContext&) override;
+       QueryData generate(QueryContext&) override;
        QueryData update(QueryContext&, const PluginRequest& request) override;
 };
 
diff --git a/src/vist/table/util.cpp b/src/vist/table/util.cpp
new file mode 100644 (file)
index 0000000..aa6ebdb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include "util.hpp"
+
+#include <vist/logger.hpp>
+
+namespace vist {
+namespace table {
+
+QueryData exception_guard(const std::function<QueryData()>& func) try
+{
+       return func();
+} catch (const vist::Exception<ErrCode>& e)
+{
+       ERROR(VIST) << "Failed while excuting query: " << e.what();
+       Row r;
+       return { r };
+} catch (...)
+{
+       ERROR(VIST) << "Failed to query with unknown exception.";
+       Row r;
+       return { r };
+}
+
+QueryData success()
+{
+       Row r;
+       r["status"] = "success";
+       return QueryData { r };
+}
+
+} // namespace table
+} // namespace vist
diff --git a/src/vist/table/util.hpp b/src/vist/table/util.hpp
new file mode 100644 (file)
index 0000000..a221e7c
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <vist/exception.hpp>
+
+#include <functional>
+
+#include <osquery/tables.h>
+
+using namespace osquery;
+
+#define TABLE_EXCEPTION_GUARD_START return vist::table::exception_guard([&]() {
+#define TABLE_EXCEPTION_GUARD_END   });
+
+namespace vist {
+namespace table {
+
+QueryData exception_guard(const std::function<QueryData()>&);
+
+QueryData success();
+
+} // namespace table
+} // namespace vist