1. 程式人生 > >skipper filter 擴充套件開發

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