Skip to content

Commit

Permalink
WIP #14.
Browse files Browse the repository at this point in the history
  • Loading branch information
Enfernuz committed May 19, 2018
1 parent 0a20e76 commit d6cc6e6
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 109 deletions.
45 changes: 31 additions & 14 deletions impl/new-request-handler.lua
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
package.path = "../?.lua;" .. package.path

local protobuf_request_response_serde = require("impl.protobuf_request_response_serde")
local procedure_caller = require("impl.procedure_caller")
local json = require("utils.json")

-----

local handlers = {}

handlers["protobuf"] = function (protobuf_request)
handlers["protobuf"] = {

local request = protobuf_request_response_serde.deserialize_request(protobuf_request)
local deserialized_response = procedure_caller.carry_out(request)
return protobuf_request_response_serde.serialize_response(deserialized_response)
end
request_deserializer = protobuf_request_response_serde.deserialize_request,
response_serializer = protobuf_request_response_serde.serialize_response
}

handlers["json"] = function (json_request)
return procedure_caller.carry_out( json.decode(json_request) )
end

handlers["json"] = {

request_deserializer = function (request)
local deserialized_request = json.decode(request)
return deserialized_request.method, deserialized_request.params, deserialized_request.id
end,

response_serializer = function (response)

response.jsonrpc = "2.0"
return json.encode(response)
end
}

-----

-----

Expand All @@ -37,13 +48,19 @@ function RequestHandler:new (serde_protocol)
error( string.format("Unsupported serialization/deserialization protocol: %s.", serde_protocol) )
end

function obj:handle (request)

if request == nil then error("No request provided.", 2) end

return handler(request)
local request_deserializer = handlers[serde_protocol].request_deserializer
local response_serializer = handlers[serde_protocol].response_serializer

function obj:deserialize_request (request)
if request == nil then error("No request provided.") end
return request_deserializer(request)
end

function obj:serialize_response (response)
if response == nil then error("No response provided.") end
return response_serializer(response)
end

setmetatable(obj, self)
self.__index = self

Expand Down
57 changes: 0 additions & 57 deletions impl/procedure_caller.lua

This file was deleted.

79 changes: 79 additions & 0 deletions impl/procedure_wrappers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
-- Lua functions
local error = assert(error, "The error function is missing.")
local string = assert(string, "The string function is missing.")
local pcall = assert(pcall, "The pcall function is missing.")
local pairs = assert(pairs, "The pairs function is missing.")
local tostring = assert(tostring, "The tostring function is missing.")

-- QLua functions
local isConnected = assert(isConnected, "The message function is missing.")
local getScriptPath = assert(getScriptPath, "The getScriptPath function is missing.")
local getInfoParam = assert(getInfoParam, "The getInfoParam function is missing.")
local getItem = assert(getItem, "The getItem function is missing.")
local message = assert(message, "The message function is missing.")

-- Utility modules
local utils = require("utils.utils")

-----
-- The DataSources in-memory storage.
-- Warning: the storage may cause memory leaks if the datasources that aren't needed anymore have not been explicitly closed by the clients,
-- because the datasources' objects would never be eligible for garbage collection (whereas in a local script they are as soon as the script exits the main function).
local datasources = {}
local function get_datasource (datasource_uid)
return assert(datasources[datasource_uid], string.format("DataSource c uuid='%s' не найден.", datasource_uid))
end

-----

local function to_string_string_table (t)

local result = {}
for k, v in pairs(t) do
result[utils.Cp1251ToUtf8(tostring(k))] = utils.Cp1251ToUtf8(tostring(v))
end

return result
end

-----

local module = {}

module["isConnected"] = function ()
return isConnected()
end

module["getScriptPath"] = function ()
return getScriptPath()
end

module["getInfoParam"] = function (args)
return getInfoParam(args.param_name)
end

module["message"] = function (args)

local proc_result = message(utils.Utf8ToCp1251(args.message), args.icon_type)

if proc_result == nil then
if args.icon_type == nil then
error( string.format("Процедура message(%s) возвратила nil.", args.message) )
else
error( string.format("Процедура message(%s, %d) возвратила nil.", args.message, args.icon_type) )
end
end

return proc_result
end

module["getItem"] = function (args)

local proc_result = getItem(args.table_name, args.index)

return to_string_string_table(proc_result)
end

-----

return module
55 changes: 55 additions & 0 deletions impl/protobuf_helper.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package.path = "../?.lua;" .. package.path

local qlua = require("qlua.api")
local utils = require("utils.utils")

local module = {}

Expand All @@ -9,6 +10,46 @@ local procedure_types = {}
local args_prototypes = {}
local result_object_mappers = {}

-- unknown
method_names[qlua.RPC.ProcedureType.PROCEDURE_TYPE_UNKNOWN] = "unknown"
procedure_types[method_names[qlua.RPC.ProcedureType.PROCEDURE_TYPE_UNKNOWN]] = qlua.RPC.ProcedureType.PROCEDURE_TYPE_UNKNOWN

-- isConnected
method_names[qlua.RPC.ProcedureType.IS_CONNECTED] = "isConnected"
procedure_types[method_names[qlua.RPC.ProcedureType.IS_CONNECTED]] = qlua.RPC.ProcedureType.IS_CONNECTED
args_prototypes[qlua.RPC.ProcedureType.IS_CONNECTED] = nil
result_object_mappers[method_names[qlua.RPC.ProcedureType.IS_CONNECTED]] = function (proc_result)

local result = qlua.isConnected.Result()
result.is_connected = proc_result

return result
end

-- getScriptPath
method_names[qlua.RPC.ProcedureType.GET_SCRIPT_PATH] = "getScriptPath"
procedure_types[method_names[qlua.RPC.ProcedureType.GET_SCRIPT_PATH]] = qlua.RPC.ProcedureType.GET_SCRIPT_PATH
args_prototypes[qlua.RPC.ProcedureType.GET_SCRIPT_PATH] = nil
result_object_mappers[method_names[qlua.RPC.ProcedureType.GET_SCRIPT_PATH]] = function (proc_result)

local result = qlua.getScriptPath.Result()
result.script_path = proc_result

return result
end

-- getInfoParam
method_names[qlua.RPC.ProcedureType.GET_INFO_PARAM] = "getInfoParam"
procedure_types[method_names[qlua.RPC.ProcedureType.GET_INFO_PARAM]] = qlua.RPC.ProcedureType.GET_INFO_PARAM
args_prototypes[qlua.RPC.ProcedureType.GET_INFO_PARAM] = qlua.getInfoParam.Request
result_object_mappers[method_names[qlua.RPC.ProcedureType.GET_INFO_PARAM]] = function (proc_result)

local result = qlua.getInfoParam.Result()
result.info_param = proc_result

return result
end

-- message
method_names[qlua.RPC.ProcedureType.MESSAGE] = "message"
procedure_types[method_names[qlua.RPC.ProcedureType.MESSAGE]] = qlua.RPC.ProcedureType.MESSAGE
Expand All @@ -20,6 +61,20 @@ result_object_mappers[method_names[qlua.RPC.ProcedureType.MESSAGE]] = function (
return result
end

-- getItem
method_names[qlua.RPC.ProcedureType.GET_ITEM] = "getItem"
procedure_types[method_names[qlua.RPC.ProcedureType.GET_ITEM]] = qlua.RPC.ProcedureType.GET_ITEM
args_prototypes[qlua.RPC.ProcedureType.GET_ITEM] = qlua.getItem.Request
result_object_mappers[method_names[qlua.RPC.ProcedureType.GET_ITEM]] = function (proc_result)

local result = qlua.getItem.Result()
if proc_result then
utils.new_put_to_string_string_pb_map(proc_result, result.table_row, qlua.getItem.Result.TableRowEntry)
end

return result
end

-----

function module.get_method_name (pb_procedure_type)
Expand Down
36 changes: 17 additions & 19 deletions impl/protobuf_request_response_serde.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ local pb_helper = require("impl.protobuf_helper")
local module = {}

function module.deserialize_request (serialized_request)

local request = qlua.RPC.Request()
request:ParseFromString(serialized_request)

Expand All @@ -31,27 +31,25 @@ function module.deserialize_request (serialized_request)
end

function module.serialize_response (deserialized_response)

local response = qlua.RPC.Response()

local proc_type = pb_helper.get_protobuf_procedure_type[deserialized_response.method]
if proc_type then
response.type = proc_type
else
error( string.format("There's no protobuf QLua ProcedureType mapped to the function's name %s", deserialized_response.method) )
end

if deserialized_response.is_error then
local err = deserialized_response.error
if err then
response.is_error = true
if deserialized_response.result then
response.result = deserialized_response.result
else
--TODO: maybe set a generic error message
end
response.result = err.message -- TODO: write the full error object
else
if deserialized_response.result then
local object_mapper = pb_helper.get_protobuf_result_object_mapper(deserialized_response.method)
response.result = object_mapper(deserialized_response.result):SerializeToString()
local result = deserialized_response.result
local method = result.method
response.type = pb_helper.get_protobuf_procedure_type(method)
if not response.type then
-- TODO: make the message in Russian
error( string.format("Для QLua-функции '%s' не найден соответствующий тип процедуры protobuf.", method) )
end

local data = result.data
if data then
local object_mapper = pb_helper.get_protobuf_result_object_mapper(method)
response.result = object_mapper(data):SerializeToString()
end
end

Expand Down
2 changes: 1 addition & 1 deletion impl/rpc-handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ local qlua_procedure_caller = require("impl.qlua-procedure-caller")

local module = {

_VERSION = '0.2.0'
_VERSION = '0.3.0'
}

local datasources = {}
Expand Down
Loading

0 comments on commit d6cc6e6

Please sign in to comment.