1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
--
-- (C) 2013-22 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
package.path = dirs.installdir .. "/scripts/lua/modules/datasources/?.lua;" .. package.path
local json = require "dkjson"
local rest_utils = require "rest_utils"
local template = require "resty.template"
-- Import the classes library.
local classes = require "classes"
-- ##############################################
local datasource = classes.class()
-- ##############################################
-- This is the base REST prefix for all the available datasources
datasource.BASE_REST_PREFIX = "/lua/rest/v1/get/datasource/"
-- ##############################################
-- @brief Base class constructor
function datasource:init()
self._dataset_params = {} -- Holds per-dataset params
self._datamodel_instance = nil -- Instance of the datamodel holding data for each dataset
end
-- ##############################################
-- @brief Parses params
-- @param params_table A table with submitted params
-- @return True if parameters parsing is successful, false otherwise
function datasource:read_params(params_table)
if not params_table then
self.parsed_params = nil
return false
end
self.parsed_params = {}
for _, param in pairs(self.meta.params or {}) do
local parsed_param = params_table[param]
-- Assumes all params mandatory and not empty
-- May override this behavior in subclasses
if isEmptyString(parsed_param) then
-- Reset any possibly set param
self.parsed_params = nil
return false
end
self.parsed_params[param] = parsed_param
end
-- Ok, parsin has been successful
return true
end
-- ##############################################
-- @brief Parses params submitted along with the REST endpoint request. If parsing fails, a REST error is sent.
-- @param params_table A table with submitted params, either _POST or _GET
-- @return True if parameters parsing is successful, false otherwise
function datasource:_rest_read_params(params_table)
if not self:read_params(params_table) then
rest_utils.answer(rest_utils.consts.err.widgets_missing_datasource_params)
return false
end
return true
end
-- ##############################################
-- @brief Send datasource data via REST
function datasource:rest_send_response()
-- Make sure this is a direct REST request and not just a require() that needs this class
if not _SERVER -- Not executing a Lua script initiated from the web server (i.e., backend execution)
or not _SERVER["URI"] -- Cannot reliably determine if this is a REST request
or not _SERVER["URI"]:starts(datasource.BASE_REST_PREFIX) -- Web Lua script execution but not for this REST endpoint
then
-- Don't send any REST response
return
end
if not self:_rest_read_params(_POST) then
-- Params parsing has failed, error response already sent by the caller
return
end
self:fetch()
rest_utils.answer(
rest_utils.consts.success.ok,
self.datamodel_instance:get_data()
)
end
-- ##############################################
-- @brief Deserializes REST endpoint response into an internal datamodel
-- @param rest_response_data Response data as obtained from the REST call
function datasource:deserialize(rest_response_data)
if rest_response_data and rest_response_data.RESPONSE_CODE == 200 then
local data = json.decode(rest_response_data.CONTENT)
local when = os.time()
if data and data.rc == rest_utils.consts.success.ok.rc then
self.datamodel_instance = self.meta.datamodel:new(data.rsp.header)
for _, row in ipairs(data.rsp.rows) do
self.datamodel_instance:appendRow(when, data.rsp.header, row)
end
end
end
end
-- ##############################################
-- @brief Returns instance metadata, which depends on the current instance and parsed_params
function datasource:get_metadata()
local res = {}
-- Render a url with submitted parsed_params
if self.meta.url then
local url_func = template.compile(self.meta.url, nil, true)
local url_rendered = url_func({
params = self.parsed_params,
})
res["url"] = url_rendered
end
return res
end
-- ##############################################
-- @brief Transform data according to the specified transformation
-- @param data The data to be transformed
-- @param transformation The transformation to be applied
-- @return transformed data
function datasource:transform(transformation)
return self.datamodel_instance:transform(transformation)
end
-- ##############################################
return datasource
-- ##############################################
|