首页 > 解决方案 > Kong插件开发-将自定义实体插入数据存储区时出错(postgres)

问题描述

我正在尝试编写自己的 Kong 插件,该插件需要存储一些自定义实体(如 api-key),但它失败了(无法插入到 postgres)并破坏了 http 请求。

这是我的插件:

架构.lua

local typedefs = require "kong.db.schema.typedefs"

-- Grab pluginname from module name
local plugin_name = ({...})[1]:match("^kong%.plugins%.([^%.]+)")

local schema = {
  name = plugin_name,
  fields = {
    -- the 'fields' array is the top-level entry with fields defined by Kong
    { consumer = typedefs.no_consumer },  -- this plugin cannot be configured on a consumer (typical for auth plugins)
    { protocols = typedefs.protocols_http },
    { config = {
        -- The 'config' record is the custom part of the plugin schema
        type = "record",
        fields = {
          -- a standard defined field (typedef), with some customizations
          { token_header = typedefs.header_name {
              required = true,
              default = "X-API-KEY" } },
          { response_header = typedefs.header_name {
              required = true,
              default = "Bye-World" } },
          { ttl = { -- self defined field
              type = "integer",
              default = 600,
              required = true,
              gt = 0, }}, -- adding a constraint for the value
        },
        entity_checks = {
          -- add some validation rules across fields
          -- the following is silly because it is always true, since they are both required
          { at_least_one_of = { "token_header", "response_header" }, },
          -- We specify that both header-names cannot be the same
          { distinct = { "token_header", "response_header"} },
        },
      },
    },
  },
}

return schema

daos.lua

-- daos.lua
local typedefs = require "kong.db.schema.typedefs"


return {
  -- this plugin only results in one custom DAO, named `myplugin`:
  myplugin = {
    name                  = "myplugin", -- the actual table in the database
    endpoint_key          = "key",
    primary_key           = { "key" },
    cache_key             = { "key" },
    generate_admin_api    = true,
    admin_api_name        = "myplugins",
    admin_api_nested_name = "myplugin",    
    fields = {
      {
        -- a value to be inserted by the DAO itself
        -- (think of serial id and the uniqueness of such required here)
        id = typedefs.uuid,
      },
      {
        -- also interted by the DAO itself
        created_at = typedefs.auto_timestamp_s,
      },
      {
        -- a unique API key
        key = {
          type      = "string",
          required  = false,
          unique    = true,
          auto      = true,
        },
      },
    },
  },
}

迁移/000_base_myplugin.lua

return {
  postgres = {
    up = [[
      CREATE TABLE IF NOT EXISTS "myplugin" (
        "created_at"   TIMESTAMP WITH TIME ZONE     DEFAULT (CURRENT_TIMESTAMP(0) AT TIME ZONE 'UTC'),
        "key"          TEXT                         PRIMARY KEY
      );
      DO $$
      BEGIN
        CREATE INDEX IF NOT EXISTS "myplugin_key_idx" ON "myplugin" ("key");
      EXCEPTION WHEN UNDEFINED_COLUMN THEN
        -- Do nothing, accept existing state
      END$$;
    ]],
  },

  cassandra = {
    up = [[
      CREATE TABLE IF NOT EXISTS myplugin(
        created_at  timestamp,
        key         text PRIMARY KEY,
      );
      CREATE INDEX IF NOT EXISTS ON myplugin(key);
    ]],
  },
}

处理程序.lua

local plugin = {
  PRIORITY = 1000, -- set the plugin priority, which determines plugin execution order
  VERSION = "0.1",
}

function plugin:init_worker()

  kong.log.debug("saying hi from the 'init_worker' handler")

end --]]

-- runs in the 'header_filter_by_lua_block'
function plugin:header_filter(plugin_conf)

  local entity, err = kong.db.myplugin:insert({
    key = "testkey",
  })

  if not entity then
    kong.log.err("Error when inserting myplugin key: " .. err)
    return nil
  end

end --]]

return plugin

但是当我提出请求时,没有数据插入数据存储区:

kong_tests=# select * from myplugin;
 created_at | key 
------------+-----
(0 rows)

和http响应:

[Kong-2.3.3:/kong]# curl -I -H "Host: example.com" http://localhost:8000/
curl: (52) Empty reply from server

Kong 错误日志:

2021/04/16 15:19:46 [error] 160#0: *5597 failed to run header_filter_by_lua*: /usr/local/share/lua/5.1/kong/globalpatches.lua:389: API disabled in the context of header_filter_by_lua*
stack traceback:
  [C]: in function 'error'
  /usr/local/openresty/lualib/resty/core/socket_tcp.lua:177: in function 'old_tcp'
  /usr/local/share/lua/5.1/kong/globalpatches.lua:389: in function 'tcp'
  /usr/local/share/lua/5.1/pgmoon/socket.lua:93: in function 'new'
  /usr/local/share/lua/5.1/pgmoon/init.lua:676: in function '__init'
  /usr/local/share/lua/5.1/pgmoon/init.lua:700: in function 'new'
  .../share/lua/5.1/kong/db/strategies/postgres/connector.lua:203: in function 'connect'
  .../share/lua/5.1/kong/db/strategies/postgres/connector.lua:528: in function 'execute'
  ...local/share/lua/5.1/kong/db/strategies/postgres/init.lua:579: in function 'insert'
  /usr/local/share/lua/5.1/kong/db/dao/init.lua:1115: in function 'insert'
  /kong-plugin/kong/plugins/myplugin/handler.lua:96: in function </kong-plugin/kong/plugins/myplugin/handler.lua:76>
  /usr/local/share/lua/5.1/kong/init.lua:265: in function 'execute_plugins_iterator'
  /usr/local/share/lua/5.1/kong/init.lua:1115: in function 'header_filter'
  header_filter_by_lua:2: in main chunk while reading response header from upstream, client: 127.0.0.1, server: kong, request: "HEAD / HTTP/1.1", upstream: "https://172.67.201.247:443/bin/91589399-57f7-4d16-9550-8f08f2719533", host: "example.com"

我错过了什么?提前致谢!<3

标签: postgresqlluakongkong-plugin

解决方案


推荐阅读