• apisix插件开发值的获取


    本地变量

    本地声明的常量, 直接使用

    local ALGORITHM = "SHA256"
    
    -- 生成签名
    local function generate_signature(rsa_private_key, signing_string)
        local privateObject, err = resty_rsa:new({ private_key = rsa_private_key, algorithm = ALGORITHM })
        if not privateObject then
            return nil, err
        end
    
        local signature, err = privateObject:sign(signing_string)
        if not signature then
            return nil, err
        end
    
        return signature
    end
    

    配置

    启用插件时, 输入的配置
    以 echo.lua 插件举例

    启用echo插件需要的配置

    -- 启用插件时, 需要填写的配置, 最后一行的意思是, 必须填一个
    local schema = {
        type = "object",
        properties = {
            before_body = {
                description = "body before the filter phase.",
                type = "string"
            },
            body = {
                description = "body to replace upstream response.",
                type = "string"
            },
            after_body = {
                description = "body after the modification of filter phase.",
                type = "string"
            },
            headers = {
                description = "new headers for response",
                type = "object",
                minProperties = 1,
            },
        },
        anyOf = {
            {required = {"before_body"}},
            {required = {"body"}},
            {required = {"after_body"}}
        },
        minProperties = 1,
    }
    

    启用echo插件

    curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
    {
        "plugins": {
            "echo": {
                "before_body": "before the body modification "
            }
        },
        "upstream": {
            "nodes": {
                "127.0.0.1:9081": 1
            },
            "type": "roundrobin"
        },
        "uri": "/hello"
    }'
    

    配置的获取

    conf.before_body
    
    function _M.body_filter(conf, ctx)
        if conf.body then
            ngx.arg[1] = conf.body
            ngx.arg[2] = true
        end
    
        if conf.before_body and not ctx.plugin_echo_body_set then
            ngx.arg[1] = conf.before_body ..  ngx.arg[1]
            ctx.plugin_echo_body_set = true
        end
    
        if ngx.arg[2] and conf.after_body then
            ngx.arg[1] = ngx.arg[1] .. conf.after_body
        end
    end
    

    属性

    属性需要配置在配置文件中, 需重启
    以log-rotate.lua插件为例

    配置文件路径以及配置内容

    # 配置文件路径
    vim /usr/local/apisix/conf/config.yaml
    
    # 插件属性配置
    plugin_attr:
      log-rotate:
        interval: 1800    # rotate interval (unit: second)
        max_kept: 20    # max number of log files will be kept
        enable_compression: true    # enable log file compression(gzip) or not, default false
    

    属性获取

    local plugin = require("apisix.plugin")
    
    local plugin_name = "echo"
    
    local function rotate()
        local interval = INTERVAL
        local max_kept = MAX_KEPT
        local attr = plugin.plugin_attr(plugin_name)
        if attr then
            interval = attr.interval or interval
            max_kept = attr.max_kept or max_kept
            enable_compression = attr.enable_compression or enable_compression
        end
    end
    

    元数据

    参考example-plugin.lua

    配置

    -- 需要一个ikey, 一个skey
    local metadata_schema = {
        type = "object",
        properties = {
            ikey = {type = "number", minimum = 0},
            skey = {type = "string"},
        },
        required = {"ikey", "skey"},
    }
    

    修改

    curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/example-plugin  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -i -X PUT -d '
    {
        "skey": "val",
        "ikey": 1
    }'
    HTTP/1.1 201 Created
    Date: Thu, 26 Dec 2019 04:19:34 GMT
    Content-Type: text/plain
    

    存储

    元数据的存储存在etcd中

    # 路径
    etcdctl get /apisix/plugin_metadata/example-plugin
    
    # 保存在etcd中的数据格式
    /apisix/plugin_metadata/example-plugin
    {"skey":"val","ikey":1}
    

    获取

    local plugin = require("apisix.plugin")
    
    local plugin_name = "example-plugin"
    
    # 获取并打印
    local metadata = plugin.plugin_metadata(plugin_name)
    core.log.warn("metadata: ", core.json.encode(metadata))
    
    # 代码中的数据格式
    {"value":{"skey":"val","ikey":1,"id":"plugin-test"}
    

    注意事项以及其他说明

    • 元数据不在代码中声明, 也是可以直接调用接口修改的; 代码中声明, 可以控制必须入参
    • 元数据可以全局使用, 但是如果某个值不更新的话, 会被删除掉

    如下, 我修改了一个test的值, 然后再修改回去的时候, test已经没有了, 不会一直存在

    curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/example-plugin  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -i -X PUT -d '
    {
        "skey": "val2",
        "ikey": 2,
        "test": "test"
    }'
    
    curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/example-plugin  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -i -X PUT -d '
    {
        "skey": "val3",
        "ikey": 5
    }'
    

    参考文档

    https://apisix.apache.org/zh/docs/apisix/admin-api/#plugin-metadata

    etcd

    如果想让某个插件, 或者所有插件使用一个全局变量值的话, 可以放在etcd中

    etcd客户端的插入, 查询

    # 插入
    etcdctl put /apisix/plugin-test/test 5
    
    # 获取
    etcdctl get /apisix/plugin-test/test 5
    
    # 删除
    etcdctl del /apisix/takin-apisix-server/cluster
    

    apisix中etcd插入, 查询

    注意: apisix操作etcd, 默认前缀为 /apisix

    local core = require("apisix.core")
    
    # 插入
    local res, err = core.etcd.set(key, value)
    
    # 获取
    local res, err = core.etcd.get(key)
    core.log.warn("res: ", core.json.encode(res.body))
    
    # 获取的数据结构, 数据在res.body.node.value下
    {"header":{"revision":"8096","cluster_id":"14841639068965178418","raft_term":"60","member_id":"10276657743932975437"},"action":"get","node":{"modifiedIndex":8075,"value":{"skey":"val","ikey":1},"key":"\/apisix\/plugin_metadata\/plugin-test","createdIndex":8075},"count":"1"}
    

    插件中的使用

    使用插件可以注册接口, 通过接口, 修改etcd的值, 来使用
    注册接口参考文档 https://apisix.apache.org/zh/docs/apisix/plugin-develop/#注册公共接口

    local core = require("apisix.core")
    
    local plugin_name = "plugin-test"
    
    -- 更新接口对应的方法
    local function plugin_update()
        -- 拿到请求体, 然后反序列化
        -- 获取值, 赋值
        local body = core.request.get_body()
        if not body then
            return 500, {msg = "没有数据"}
        end
    
        local data, err = core.json.decode(body)
        if not data then
            return 500, {msg = "json反序列化失败" .. err}
        end
    
        if not data.value then
            return 500, {msg = "值必须填写"}
        end
    
        local etcd_key = xxx
        local res, err2 = core.etcd.set(etcd_key, data.value)
        if not res then
            return 500, {msg = "存入etcd失败, 详细信息: " .. err2 }
        end
    
        return 200
    end
    
    -- 公共接口
    function _M.api()
        return {
            {
                methods = {"PUT"},
                uri = "/apisix/plugin/" .. plugin_name,
                handler = plugin_update,
            }
        }
    end
    

    apisix自定义变量

    参考: https://github.com/apache/apisix/issues/6702

    注意事项

    注册的自定义变量不能作为全局变量来使用
    因为自定义变量是有生命周期的, 下一个请求就会重新生成 TODO
    自定义变量而且存在每个worker下的内存中的 TODO
    如果提供了一个接口去修改, 可能只修改了某个worker下的自定义变量

    参考文档

    https://apisix.apache.org/zh/docs/apisix/plugin-develop/#注册自定义变量

    其他

    IPC 进程间通信

  • 相关阅读:
    Silverlight 5 开发者的声音
    Android之Bundle传递数据详解与实例及Bundle与SharedPreferences的区别
    Android开源项目源码下载(不断更新中)
    Android 控件之WebView
    Android学习资料分享(不断更新中)
    Android控件之ZoomButton缩放按钮
    Android2.3操作系统即将发布,亮点解读
    Android控件之ZoomControls缩放控件
    Windows Phone 7 Silverlight控件之Map入门
    Android 控件之DatePicker,TimePicker,Calender
  • 原文地址:https://www.cnblogs.com/loseself/p/16157785.html
Copyright © 2020-2023  润新知