Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ etcd:

plugins:
- example_plugin
- not_exist_plugin
5 changes: 2 additions & 3 deletions lua/apimeta/core/config.lua
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
-- Copyright (C) Yuansheng Wang

local ngx = ngx
local pcall = pcall
local yaml = require("apimeta.core.yaml")
local io_open = io.open

local type = type
local config_path = ngx.config.prefix() .. "conf/config.yaml"

local _M = {}

local function read_file(path)
local file = io_open(path, "rb") -- r read mode and b binary mode
local file = io_open(path, "rb") -- read and binary mode
if not file then
return nil
end
Expand Down
47 changes: 47 additions & 0 deletions lua/apimeta/plugin.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
local require = require
local config = require("apimeta.core.config")
local typeof = require("apimeta.core.typeof")
local log = require("apimeta.core.log")
local new_tab = require("table.new")
local insert_tab = table.insert
local sort_tab = table.sort
local tostring = tostring
local pcall = pcall
local ipairs = ipairs
local pairs = pairs


local _M = {
Expand All @@ -19,5 +27,44 @@ function _M.check_args(args, scheme)
return true
end

local function sort_plugin(l, r)
return l.priority > r.priority
end

function _M.load()
local plugin_names = config.read().plugins
if not plugin_names then
return nil, "failed to read plugin list form local file"
end

local plugins = new_tab(#plugin_names, 0)
for _, name in ipairs(plugin_names) do
local ok, plugin = pcall(require, "apimeta.plugins." .. name)
if not ok then
log.error("failed to load plugin ", name, " err: ", plugin)

elseif not plugin.priority then
log.error("invalid plugin", name, ", missing field: priority")

elseif not plugin.check_args then
log.error("invalid plugin", name, ", missing method: check_args")

elseif not plugin.version then
log.error("invalid plugin", name, ", missing field: version")

else
plugin.name = name
insert_tab(plugins, plugin)
end
end

-- sort by plugin's priority
if #plugins > 1 then
sort_tab(plugins, sort_plugin)
end

return plugins
end


return _M
9 changes: 7 additions & 2 deletions lua/apimeta/plugins/example_plugin.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
local plugin = require("apimeta.plugin")


-- TODO: need a more powerful way to define the schema
local args_schema = {
i = "int", -- value list: apimeta.core.typeof#92
i = "int", -- value list: apimeta.core.typeof#92
s = "string",
t = "table",
}


local _M = {version = 0.1}
local _M = {
version = 0.1,
priority = 1000, -- TODO: add a type field, may be a good idea
name = "example_plugin",
}


function _M.check_args(config)
Expand Down
33 changes: 30 additions & 3 deletions t/example-plugin.t
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use t::APIMeta 'no_plan';

repeat_each(1);
repeat_each(2);
no_long_string();
no_shuffle();
log_level('info');

run_tests;

__DATA__

=== TEST 1: sanity
=== TEST 1: check arguments
--- config
location /t {
content_by_lua_block {
Expand Down Expand Up @@ -44,3 +43,31 @@ failed to check args: args.i expect int value but got: [nil]
failed to check args: args.s expect string value but got: [3]
failed to check args: args.t expect table value but got: []
done



=== TEST 2: load plugins
--- config
location /t {
content_by_lua_block {
local plugins, err = require("apimeta.plugin").load()
if not plugins then
ngx.say("failed to load plugins: ", err)
end

local encode_json = require "cjson.safe" .encode
for _, plugin in ipairs(plugins) do
ngx.say("plugin name: ", plugin.name,
" priority: ", plugin.priority)

plugin.rewrite()
end
}
}
--- request
GET /t
--- response_body
plugin name: example_plugin priority: 1000
--- error_log
failed to load plugin not_exist_plugin err: module 'apimeta.plugins.not_exist_plugin' not found
rewrite(): plugin rewrite phase
3 changes: 1 addition & 2 deletions t/sanity.t
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use t::APIMeta 'no_plan';

repeat_each(1);
repeat_each(2);
no_long_string();
no_shuffle();
log_level('info');

run_tests();
Expand Down
5 changes: 2 additions & 3 deletions t/yaml-config.t
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use t::APIMeta 'no_plan';

repeat_each(1);
repeat_each(2);
no_long_string();
no_shuffle();
log_level('info');

run_tests;
Expand All @@ -26,4 +25,4 @@ GET /t
--- response_body
etcd host: http://127.0.0.1:2379
etcd prefix: /v2/keys
plugins: ["example_plugin"]
plugins: ["example_plugin","not_exist_plugin"]