skipper filter 扩展开发

skipper 的扩展包含filter类型的,以及Predicates ,当然script(lua)脚本也是
这次主要是filter类型的开发

filter 接口约定

  • 格式
    filter 至少需要包含spec&&filter 类型
    spec 包含用户初始化filter 必备的参数,spec 必须实现的方法
Name() string
CreateFilter([]interface{}) (filters.Filter,error)

filter 的实现必须满足Filter 接口的

Request(filters.FilterContext)
Response(filters.FilterContext)
对于需要进行资源清理的,使用Close 方法

参考代码模版

type myFilter struct{}

func NewMyFilter() filters.Spec {
    return &myFilter{}
}

func (spec *myFilter) Name() string { return "myFilter" }

func (spec *myFilter) CreateFilter(config []interface{}) (filters.Filter, error) {
     return NewMyFilter(), nil
}

func (f *myFilter) Request(ctx filters.FilterContext) {
     // change data in ctx.Request() for example
}

func (f *myFilter) Response(ctx filters.FilterContext) {
     // change data in ctx.Response() for example
}

简单demo

实现比较简单,就是在请求header中添加一个token 值

  • 代码位置
    直接放到代码的filters目录中
  • 代码说明
    很简单,就是在response 阶段添加token
package myfilter

import (
    "github.com/zalando/skipper/filters"
)

const (
    name = "myfilterToken"
    defaultToken = "dalongrong"
)

type basicSpec struct {
}

type filter struct {
    allowTokens []string
}

func NewDefaultToken() filters.Spec {
    return &basicSpec{}
}

func (a filter) Response(ctx filters.FilterContext) {
    if len(a.allowTokens) == 0 {
        ctx.Response().Header.Add(defaultToken, "default-rongfengliang")
        return
    }

    token := ctx.Request().Header.Get(defaultToken)
    if token == "" {
        return
    }
    for _, o := range a.allowTokens {
        if o == token {
            ctx.Response().Header.Add(defaultToken, o)
            return
        }
    }
}

// Request is a noop
func (a filter) Request(filters.FilterContext) {}

// CreateFilter takes an optional string array.
// If any argument is not a string, it will return an error
func (spec basicSpec) CreateFilter(args []interface{}) (filters.Filter, error) {
    f := &filter{}
    for _, a := range args {
        if s, ok := a.(string); ok {
            f.allowTokens = append(f.allowTokens, s)
        } else {
            return nil, filters.ErrInvalidFilterParameters
        }
    }
    return f, nil
}

func (spec basicSpec) Name() string { return name }
  • 注册filter
    buildin代码中添加注册
    import (
+   "github.com/zalando/skipper/filters/myfilter"
     )

    func MakeRegistry() filters.Registry {

+    myfilter.NewDefaultToken(),

构建&&使用

注意有依赖包的问题,注意合理上网

  • 构建
make build
  • 使用
./bin/skipper -address :9999 -inline-routes 'r: * -> setQuery("lang", "pt")->myfilterToken() -> "http://10.15.0.80"'
  • 测试效果

说明

因为新版本使用了golang 的mod 所以会有版本的要求,使用docker 进行构建可能会更方便,其中官方文档有
比较详细的如果开发一个filter,包含测试,文档

参考资料

http://opensource.zalando.com/skipper/reference/development/#how-to-develop-a-filter
https://github.com/rongfengliang/skipper-docker-build

猜你喜欢

转载自www.cnblogs.com/rongfengliang/p/10071520.html