diff --git a/plugins/wasm-go/extensions/basic-auth/go.mod b/plugins/wasm-go/extensions/basic-auth/go.mod index 7ccd8a332a..c5f1273636 100644 --- a/plugins/wasm-go/extensions/basic-auth/go.mod +++ b/plugins/wasm-go/extensions/basic-auth/go.mod @@ -3,6 +3,7 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/basic-auth go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0 diff --git a/plugins/wasm-go/extensions/chatgpt-proxy/go.mod b/plugins/wasm-go/extensions/chatgpt-proxy/go.mod index f2800cdca9..6e53be18df 100644 --- a/plugins/wasm-go/extensions/chatgpt-proxy/go.mod +++ b/plugins/wasm-go/extensions/chatgpt-proxy/go.mod @@ -3,6 +3,7 @@ module chatgpt-proxy go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230629030002-81e467b6242d diff --git a/plugins/wasm-go/extensions/cors/go.mod b/plugins/wasm-go/extensions/cors/go.mod index e2ddc75c4d..b304762c1b 100644 --- a/plugins/wasm-go/extensions/cors/go.mod +++ b/plugins/wasm-go/extensions/cors/go.mod @@ -3,6 +3,7 @@ module cors go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230519024024-625c06e58f91 diff --git a/plugins/wasm-go/extensions/de-graphql/go.mod b/plugins/wasm-go/extensions/de-graphql/go.mod index fbeaac2753..c3e391d83b 100644 --- a/plugins/wasm-go/extensions/de-graphql/go.mod +++ b/plugins/wasm-go/extensions/de-graphql/go.mod @@ -3,6 +3,7 @@ module de-graphql go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230410091208-df60dd43079c diff --git a/plugins/wasm-go/extensions/gc-test/go.mod b/plugins/wasm-go/extensions/gc-test/go.mod index db75d9de59..1e00f67b36 100644 --- a/plugins/wasm-go/extensions/gc-test/go.mod +++ b/plugins/wasm-go/extensions/gc-test/go.mod @@ -3,7 +3,7 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/gc-test go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. - +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd replace github.com/wasilibs/nottinygc v0.5.1 => github.com/higress-group/nottinygc v0.0.0-20231019105920-c4d985d443e1 require ( diff --git a/plugins/wasm-go/extensions/gw-error-format/go.mod b/plugins/wasm-go/extensions/gw-error-format/go.mod index dd9b36d65d..44432b4fd6 100644 --- a/plugins/wasm-go/extensions/gw-error-format/go.mod +++ b/plugins/wasm-go/extensions/gw-error-format/go.mod @@ -3,6 +3,7 @@ module wasm-demo go 1.18 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0 diff --git a/plugins/wasm-go/extensions/hello-world/go.mod b/plugins/wasm-go/extensions/hello-world/go.mod index 04d00ddd93..44115fc425 100644 --- a/plugins/wasm-go/extensions/hello-world/go.mod +++ b/plugins/wasm-go/extensions/hello-world/go.mod @@ -3,6 +3,7 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/hello-world go 1.18 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0 diff --git a/plugins/wasm-go/extensions/http-call/go.mod b/plugins/wasm-go/extensions/http-call/go.mod index b82a38d143..540cae23fd 100644 --- a/plugins/wasm-go/extensions/http-call/go.mod +++ b/plugins/wasm-go/extensions/http-call/go.mod @@ -3,6 +3,7 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/http-call go 1.18 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0 diff --git a/plugins/wasm-go/extensions/key-auth/go.mod b/plugins/wasm-go/extensions/key-auth/go.mod index 6a4e5f9abe..187b280a9f 100644 --- a/plugins/wasm-go/extensions/key-auth/go.mod +++ b/plugins/wasm-go/extensions/key-auth/go.mod @@ -3,6 +3,7 @@ module key-auth go 1.19 replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20231017105619-a18879bf867c diff --git a/plugins/wasm-go/extensions/oidc/go.mod b/plugins/wasm-go/extensions/oidc/go.mod index 98db752e20..55a0165276 100644 --- a/plugins/wasm-go/extensions/oidc/go.mod +++ b/plugins/wasm-go/extensions/oidc/go.mod @@ -2,6 +2,8 @@ module oidc go 1.19 +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd + require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230807053545-d307d0e755f1 github.com/go-jose/go-jose/v3 v3.0.0 diff --git a/plugins/wasm-go/extensions/request-block/go.mod b/plugins/wasm-go/extensions/request-block/go.mod index cb40f84f48..33355661d3 100644 --- a/plugins/wasm-go/extensions/request-block/go.mod +++ b/plugins/wasm-go/extensions/request-block/go.mod @@ -2,7 +2,10 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/request-block go 1.18 -replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace ( + github.com/alibaba/higress/plugins/wasm-go => ../.. + github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd +) require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0 diff --git a/plugins/wasm-go/extensions/simple-jwt-auth/go.mod b/plugins/wasm-go/extensions/simple-jwt-auth/go.mod index 750c01abd4..6576eaea10 100644 --- a/plugins/wasm-go/extensions/simple-jwt-auth/go.mod +++ b/plugins/wasm-go/extensions/simple-jwt-auth/go.mod @@ -2,6 +2,11 @@ module jwt-auth go 1.19 +replace ( + github.com/alibaba/higress/plugins/wasm-go => ../.. + github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd +) + require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230811015533-49269b43032f github.com/dgrijalva/jwt-go v3.2.0+incompatible diff --git a/plugins/wasm-go/extensions/sni-misdirect/go.mod b/plugins/wasm-go/extensions/sni-misdirect/go.mod index c6ae41a333..a87d0e3fe3 100644 --- a/plugins/wasm-go/extensions/sni-misdirect/go.mod +++ b/plugins/wasm-go/extensions/sni-misdirect/go.mod @@ -2,6 +2,11 @@ module wasm_go/higress/plugins/wasm-go/extensions/sni_misdirect go 1.19 +replace ( + github.com/alibaba/higress/plugins/wasm-go => ../.. + github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd +) + require ( github.com/alibaba/higress/plugins/wasm-go v1.3.1 github.com/tetratelabs/proxy-wasm-go-sdk v0.22.0 diff --git a/plugins/wasm-go/extensions/transformer/go.mod b/plugins/wasm-go/extensions/transformer/go.mod index 15a059b667..e2f0e958a1 100644 --- a/plugins/wasm-go/extensions/transformer/go.mod +++ b/plugins/wasm-go/extensions/transformer/go.mod @@ -2,7 +2,10 @@ module github.com/alibaba/higress/plugins/wasm-go/extensions/transformer go 1.19 -replace github.com/alibaba/higress/plugins/wasm-go => ../.. +replace ( + github.com/alibaba/higress/plugins/wasm-go => ../.. + github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd +) require ( github.com/alibaba/higress/plugins/wasm-go v0.0.0-20230829022308-8747e1ddadf0 diff --git a/plugins/wasm-go/go.mod b/plugins/wasm-go/go.mod index 0ef17c108c..87bc50e055 100644 --- a/plugins/wasm-go/go.mod +++ b/plugins/wasm-go/go.mod @@ -5,9 +5,10 @@ go 1.19 require ( github.com/google/uuid v1.3.0 github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 - github.com/stretchr/testify v1.8.0 + github.com/stretchr/testify v1.8.4 github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c github.com/tidwall/gjson v1.14.3 + github.com/tidwall/resp v0.1.1 ) require ( @@ -18,3 +19,5 @@ require ( github.com/tidwall/pretty v1.2.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/tetratelabs/proxy-wasm-go-sdk => github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd diff --git a/plugins/wasm-go/go.sum b/plugins/wasm-go/go.sum index b9eb358443..d3223262f2 100644 --- a/plugins/wasm-go/go.sum +++ b/plugins/wasm-go/go.sum @@ -1,29 +1,26 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520 h1:IHDghbGQ2DTIXHBHxWfqCYQW1fKjyJ/I7W1pMyUDeEA= github.com/higress-group/nottinygc v0.0.0-20231101025119-e93c4c2f8520/go.mod h1:Nz8ORLaFiLWotg6GeKlJMhv8cci8mM43uEnLA5t8iew= +github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd h1:Oo20PYxsXsUCFR0y1CWkAgiLuxf8uc85RAzntjmlfJA= +github.com/higress-group/proxy-wasm-go-sdk v0.0.0-20240105034322-9a6ac242c3dd/go.mod h1:YqR8JZaY3Ev9ihXgjzAQAMkXEzPKKmy4Q5rsVWt4XGk= github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c h1:OCUFXVGixHLfNjg6/QYEhv+jHJ5mRGhpEUVFv9eWPJE= -github.com/tetratelabs/proxy-wasm-go-sdk v0.19.1-0.20220822060051-f9d179a57f8c/go.mod h1:5t/pWFNJ9eMyu/K/Z+OeGhDJ9sN9eCo8fc2pyM/Qjg4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/resp v0.1.1 h1:Ly20wkhqKTmDUPlyM1S7pWo5kk0tDu8OoC/vFArXmwE= +github.com/tidwall/resp v0.1.1/go.mod h1:3/FrruOBAxPTPtundW0VXgmsQ4ZBA0Aw714lVYgwFa0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/plugins/wasm-go/pkg/wrapper/redis_wrapper.go b/plugins/wasm-go/pkg/wrapper/redis_wrapper.go new file mode 100644 index 0000000000..235a7ab099 --- /dev/null +++ b/plugins/wasm-go/pkg/wrapper/redis_wrapper.go @@ -0,0 +1,653 @@ +// Copyright (c) 2022 Alibaba Group Holding Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package wrapper + +import ( + "bytes" + "fmt" + "io" + + "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" + "github.com/tidwall/resp" +) + +type RedisResponseCallback func(status int, response resp.Value) + +type RedisClient interface { + Init(username, password string, timeout int64) error + Command(cmds []interface{}, callback RedisResponseCallback) error + // BatchCommands(cmds [][]interface{}, callback func(status int, response []resp.Value)) error + Eval(script string, params []interface{}, callback RedisResponseCallback) error + + // Key + Del(key string, callback RedisResponseCallback) error + Exists(key string, callback RedisResponseCallback) error + Expire(key string, ttl int, callback RedisResponseCallback) error + Persist(key string, callback RedisResponseCallback) error + + // String + Get(key string, callback RedisResponseCallback) error + Set(key string, value interface{}, callback RedisResponseCallback) error + SetEx(key string, value interface{}, ttl int, callback RedisResponseCallback) error + MGet(keys []string, callback RedisResponseCallback) error + MSet(kvMap map[string]interface{}, callback RedisResponseCallback) error + Incr(key string, callback RedisResponseCallback) error + Decr(key string, callback RedisResponseCallback) error + IncrBy(key string, delta int, callback RedisResponseCallback) error + DecrBy(key string, delta int, callback RedisResponseCallback) error + + // List + LLen(key string, callback RedisResponseCallback) error + RPush(key string, vals []interface{}, callback RedisResponseCallback) error + RPop(key string, callback RedisResponseCallback) error + LPush(key string, vals []interface{}, callback RedisResponseCallback) error + LPop(key string, callback RedisResponseCallback) error + LIndex(key string, index int, callback RedisResponseCallback) error + LRange(key string, start, stop int, callback RedisResponseCallback) error + LRem(key string, count int, value interface{}, callback RedisResponseCallback) error + LInsertBefore(key string, pivot, value interface{}, callback RedisResponseCallback) error + LInsertAfter(key string, pivot, value interface{}, callback RedisResponseCallback) error + + // Hash + HExists(key, field string, callback RedisResponseCallback) error + HDel(key string, fields []string, callback RedisResponseCallback) error + HLen(key string, callback RedisResponseCallback) error + HGet(key, field string, callback RedisResponseCallback) error + HSet(key, field string, value interface{}, callback RedisResponseCallback) error + HMGet(key string, fields []string, callback RedisResponseCallback) error + HMSet(key string, kvMap map[string]interface{}, callback RedisResponseCallback) error + HKeys(key string, callback RedisResponseCallback) error + HVals(key string, callback RedisResponseCallback) error + HGetAll(key string, callback RedisResponseCallback) error + HIncrBy(key, field string, delta int, callback RedisResponseCallback) error + HIncrByFloat(key, field string, delta float64, callback RedisResponseCallback) error + + // Set + SCard(key string, callback RedisResponseCallback) error + SAdd(key string, value []interface{}, callback RedisResponseCallback) error + SRem(key string, values []interface{}, callback RedisResponseCallback) error + SIsMember(key string, value interface{}, callback RedisResponseCallback) error + SMembers(key string, callback RedisResponseCallback) error + SDiff(key1, key2 string, callback RedisResponseCallback) error + SDiffStore(destination, key1, key2 string, callback RedisResponseCallback) error + SInter(key1, key2 string, callback RedisResponseCallback) error + SInterStore(destination, key1, key2 string, callback RedisResponseCallback) error + SUnion(key1, key2 string, callback RedisResponseCallback) error + SUnionStore(destination, key1, key2 string, callback RedisResponseCallback) error + + // Sorted Set + ZCard(key string, callback RedisResponseCallback) error + ZAdd(key string, msMap map[string]interface{}, callback RedisResponseCallback) error + ZCount(key string, min interface{}, max interface{}, callback RedisResponseCallback) error + ZIncrBy(key string, member string, delta interface{}, callback RedisResponseCallback) error + ZScore(key, member string, callback RedisResponseCallback) error + ZRank(key, member string, callback RedisResponseCallback) error + ZRevRank(key, member string, callback RedisResponseCallback) error + ZRem(key string, members []string, callback RedisResponseCallback) error + ZRange(key string, start, stop int, callback RedisResponseCallback) error + ZRevRange(key string, start, stop int, callback RedisResponseCallback) error +} + +type RedisClusterClient[C Cluster] struct { + cluster C +} + +func NewRedisClusterClient[C Cluster](cluster C) *RedisClusterClient[C] { + return &RedisClusterClient[C]{cluster: cluster} +} + +func RedisInit(cluster Cluster, username, password string, timeout uint32) error { + return proxywasm.RedisInit(cluster.ClusterName(), username, password, timeout) +} + +func RedisCall(cluster Cluster, respQuery string, callback RedisResponseCallback) error { + _, err := proxywasm.DispatchRedisCall( + cluster.ClusterName(), + respQuery, + func(status, responseSize int) { + // proxywasm.LogCriticalf("[rinfx log] responseSize is: %d", responseSize) + response, err := proxywasm.GetRedisCallResponse(0, responseSize) + if err != nil { + proxywasm.LogCriticalf("failed to get redis response body: %v", err) + } + rd := resp.NewReader(bytes.NewReader(response)) + v, _, err := rd.ReadValue() + if err != nil && err != io.EOF { + proxywasm.LogCriticalf("failed to read redis response body: %v", err) + } + // log.Infof("value: %s", v.String()) + // callback(status, v.String()) + callback(status, v) + }) + if err != nil { + proxywasm.LogCriticalf("redis call failed: %v", err) + } + return err +} + +func respString(args []interface{}) string { + var buf bytes.Buffer + wr := resp.NewWriter(&buf) + arr := make([]resp.Value, 0) + for _, arg := range args { + // arr = append(arr, resp.AnyValue(arg)) + arr = append(arr, resp.StringValue(fmt.Sprint(arg))) + } + wr.WriteArray(arr) + // proxywasm.LogCriticalf("respString:\n%s", buf.String()) + return buf.String() +} + +func (c RedisClusterClient[C]) Init(username, password string, timeout int64) error { + err := RedisInit(c.cluster, username, password, uint32(timeout)) + if err != nil { + proxywasm.LogCriticalf("failed to init redis: %v", err) + } + return err +} + +func (c RedisClusterClient[C]) Command(cmds []interface{}, callback RedisResponseCallback) error { + RedisCall(c.cluster, respString(cmds), callback) + return nil +} + +func (c RedisClusterClient[C]) Eval(script string, params []interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "eval") + args = append(args, script) + args = append(args, params...) + return RedisCall(c.cluster, respString(args), callback) +} + +// Key +func (c RedisClusterClient[C]) Del(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "del") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Exists(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "exists") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Expire(key string, ttl int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "expire") + args = append(args, key) + args = append(args, ttl) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Persist(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "persist") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +// String +func (c RedisClusterClient[C]) Get(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "get") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Set(key string, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "set") + args = append(args, key) + args = append(args, value) + RedisCall(c.cluster, respString(args), callback) + return nil +} + +func (c RedisClusterClient[C]) SetEx(key string, value interface{}, ttl int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "setex") + args = append(args, key) + args = append(args, ttl) + args = append(args, value) + RedisCall(c.cluster, respString(args), callback) + return nil +} + +func (c RedisClusterClient[C]) MGet(keys []string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "mget") + for _, k := range keys { + args = append(args, k) + } + RedisCall(c.cluster, respString(args), callback) + return nil +} + +func (c RedisClusterClient[C]) MSet(kvMap map[string]interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "mset") + for k, v := range kvMap { + args = append(args, k) + args = append(args, v) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Incr(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "incr") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) Decr(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "decr") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) IncrBy(key string, delta int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "incrby") + args = append(args, key) + args = append(args, delta) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) DecrBy(key string, delta int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "decrby") + args = append(args, key) + args = append(args, delta) + return RedisCall(c.cluster, respString(args), callback) +} + +// List +func (c RedisClusterClient[C]) LLen(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "llen") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) RPush(key string, vals []interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "rpush") + args = append(args, key) + for _, val := range vals { + args = append(args, val) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) RPop(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "rpop") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LPush(key string, vals []interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "lpush") + args = append(args, key) + for _, val := range vals { + args = append(args, val) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LPop(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "lpop") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LIndex(key string, index int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "lindex") + args = append(args, key) + args = append(args, index) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LRange(key string, start, stop int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "lrange") + args = append(args, key) + args = append(args, start) + args = append(args, stop) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LRem(key string, count int, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "lrem") + args = append(args, key) + args = append(args, count) + args = append(args, value) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LInsertBefore(key string, pivot, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "linsert") + args = append(args, key) + args = append(args, "before") + args = append(args, pivot) + args = append(args, value) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) LInsertAfter(key string, pivot, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "linsert") + args = append(args, key) + args = append(args, "after") + args = append(args, pivot) + args = append(args, value) + return RedisCall(c.cluster, respString(args), callback) +} + +// Hash +func (c RedisClusterClient[C]) HExists(key, field string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hexists") + args = append(args, key) + args = append(args, field) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HDel(key string, fields []string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hdel") + args = append(args, key) + for _, field := range fields { + args = append(args, field) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HLen(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hlen") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HGet(key, field string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hget") + args = append(args, key) + args = append(args, field) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HSet(key, field string, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hset") + args = append(args, key) + args = append(args, field) + args = append(args, value) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HMGet(key string, fields []string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hmget") + args = append(args, key) + for _, field := range fields { + args = append(args, field) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HMSet(key string, kvMap map[string]interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hmset") + args = append(args, key) + for k, v := range kvMap { + args = append(args, k) + args = append(args, v) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HKeys(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hkeys") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HVals(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hvals") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HGetAll(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hgetall") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HIncrBy(key, field string, delta int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hincrby") + args = append(args, key) + args = append(args, field) + args = append(args, delta) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) HIncrByFloat(key, field string, delta float64, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "hincrbyfloat") + args = append(args, key) + args = append(args, field) + args = append(args, delta) + return RedisCall(c.cluster, respString(args), callback) +} + +// Set +func (c RedisClusterClient[C]) SCard(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "scard") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SAdd(key string, vals []interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sadd") + args = append(args, key) + for _, val := range vals { + args = append(args, val) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SRem(key string, vals []interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "srem") + args = append(args, key) + for _, val := range vals { + args = append(args, val) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SIsMember(key string, value interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sismember") + args = append(args, key) + args = append(args, value) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SMembers(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "smembers") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SDiff(key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sdiff") + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SDiffStore(destination, key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sdiffstore") + args = append(args, destination) + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SInter(key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sinter") + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SInterStore(destination, key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sinterstore") + args = append(args, destination) + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SUnion(key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sunion") + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) SUnionStore(destination, key1, key2 string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "sunionstore") + args = append(args, destination) + args = append(args, key1) + args = append(args, key2) + return RedisCall(c.cluster, respString(args), callback) +} + +// ZSet +func (c RedisClusterClient[C]) ZCard(key string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zcard") + args = append(args, key) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZAdd(key string, msMap map[string]interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zadd") + args = append(args, key) + for m, s := range msMap { + args = append(args, s) + args = append(args, m) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZCount(key string, min interface{}, max interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zcount") + args = append(args, key) + args = append(args, min) + args = append(args, max) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZIncrBy(key string, member string, delta interface{}, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zincrby") + args = append(args, key) + args = append(args, delta) + args = append(args, member) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZScore(key, member string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zscore") + args = append(args, key) + args = append(args, member) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZRank(key, member string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zrank") + args = append(args, key) + args = append(args, member) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZRevRank(key, member string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zrevrank") + args = append(args, key) + args = append(args, member) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZRem(key string, members []string, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zrem") + args = append(args, key) + for _, m := range members { + args = append(args, m) + } + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZRange(key string, start, stop int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zrange") + args = append(args, key) + args = append(args, start) + args = append(args, stop) + return RedisCall(c.cluster, respString(args), callback) +} + +func (c RedisClusterClient[C]) ZRevRange(key string, start, stop int, callback RedisResponseCallback) error { + args := make([]interface{}, 0) + args = append(args, "zrevrange") + args = append(args, key) + args = append(args, start) + args = append(args, stop) + return RedisCall(c.cluster, respString(args), callback) +}