diff --git a/event/cloudevents/client.go b/event/cloudevents/client.go new file mode 100644 index 0000000..c2c28ea --- /dev/null +++ b/event/cloudevents/client.go @@ -0,0 +1,97 @@ +// Package cloudevents provides cloudevents client and server implementations. +package cloudevents + +import ( + "context" + "sync" + + cloudeventssdk "github.com/cloudevents/sdk-go/v2" + "github.com/cloudevents/sdk-go/v2/client" + "github.com/cloudevents/sdk-go/v2/protocol/http" +) + +type clientType int + +const ( + clientTypeHttp clientType = iota + 1 +) + +// NewHttp creates and returns a http client. +// +// ex) client, err := cloudevents.NewHttp(address, nil, nil) +func NewHttp(address string, httpOption []http.Option, clientOption []client.Option) (*Client, error) { + if protocol, err := cloudeventssdk.NewHTTP(httpOption...); err != nil { + return nil, err + } else if client, err := cloudeventssdk.NewClient(protocol, clientOption...); err != nil { + return nil, err + } else { + return &Client{clientType: clientTypeHttp, client: client, address: address}, nil + } +} + +// Client is a struct that provides client related methods. +type Client struct { + clientType clientType + + client client.Client + address string + + wgForReceiver sync.WaitGroup + cancelFuncForReceiver context.CancelFunc +} + +// Send transmits an event. +// +// ex) result := client.Send(event) +func (this *Client) Send(event Event) Result { + return Result{result: this.client.Send(this.getContext(), event)} +} + +// Send transmits an event and returns a response event. +// +// ex) responseEvent, result := client.Request(event) +func (this *Client) Request(event Event) (*Event, Result) { + responseEvent, result := this.client.Request(this.getContext(), event) + + return responseEvent, Result{result: result} +} + +// StartReceiver receives events until StopReceiver is called. +// +// ex) +// +// httpOption := []cloudeventssdk_http.Option{cloudeventssdk_http.WithPort(port)} +// receiveclient, err := cloudevents.NewHttp("", httpOption, nil) +// receiveclient.StartReceiver(handler, failureFunc) +func (this *Client) StartReceiver(handler func(context.Context, Event), failureFunc func(error)) { + this.wgForReceiver.Add(1) + go func() { + defer this.wgForReceiver.Done() + + ctx, cancel := context.WithCancel(this.getContext()) + this.cancelFuncForReceiver = cancel + + if err := this.client.StartReceiver(ctx, handler); err != nil { + failureFunc(err) + } + }() +} + +// StopReceiver stops receiving events by StartReceiver. +// +// ex)client.StopReceiver() +func (this *Client) StopReceiver() { + if this.cancelFuncForReceiver != nil { + this.cancelFuncForReceiver() + } + this.wgForReceiver.Wait() +} + +func (this *Client) getContext() context.Context { + switch this.clientType { + case clientTypeHttp: + return cloudeventssdk.ContextWithTarget(context.Background(), this.address) + default: + return nil + } +} diff --git a/event/cloudevents/client_test.go b/event/cloudevents/client_test.go new file mode 100644 index 0000000..45c7e42 --- /dev/null +++ b/event/cloudevents/client_test.go @@ -0,0 +1,84 @@ +package cloudevents_test + +import ( + "context" + "math/rand/v2" + "net/http" + "strconv" + "testing" + + cloudeventssdk_http "github.com/cloudevents/sdk-go/v2/protocol/http" + "github.com/common-library/go/event/cloudevents" +) + +func TestSend(t *testing.T) { + address, server := startServer(t) + defer stopServer(t, server) + + if client, err := cloudevents.NewHttp("http://"+address, nil, nil); err != nil { + t.Fatal(err) + } else { + for i := 0; i < 100; i++ { + if result := client.Send(getEvent(t)); result.IsUndelivered() { + t.Fatal(result.Error()) + } else if statusCode, err := result.GetHttpStatusCode(); err != nil { + t.Fatal(err) + } else if statusCode != http.StatusOK { + t.Fatal("invalid -", statusCode) + } + } + } +} + +func TestRequest(t *testing.T) { + address, server := startServer(t) + defer stopServer(t, server) + + if client, err := cloudevents.NewHttp("http://"+address, nil, nil); err != nil { + t.Fatal(err) + } else { + for i := 0; i < 100; i++ { + if event, result := client.Request(getEvent(t)); result.IsUndelivered() { + t.Fatal(result.Error()) + } else if statusCode, err := result.GetHttpStatusCode(); err != nil { + t.Fatal(err) + } else if statusCode != http.StatusOK { + t.Fatal("invalid -", statusCode) + } else { + consistencyEvent(t, event) + } + } + } +} + +func TestStartReceiver(t *testing.T) { + port := rand.IntN(1000) + 10000 + httpOption := []cloudeventssdk_http.Option{cloudeventssdk_http.WithPort(port)} + handler := func(ctx context.Context, event cloudevents.Event) { + consistencyEvent(t, &event) + } + failureFunc := func(err error) { t.Fatal(err) } + if receiveClient, err := cloudevents.NewHttp("", httpOption, nil); err != nil { + t.Fatal(err) + } else { + receiveClient.StartReceiver(handler, failureFunc) + + for i := 0; i < 100; i++ { + if sendCient, err := cloudevents.NewHttp("http://:"+strconv.Itoa(port), nil, nil); err != nil { + t.Fatal(err) + } else if result := sendCient.Send(getEvent(t)); result.IsUndelivered() { + t.Fatal(result.Error()) + } + } + + receiveClient.StopReceiver() + } +} + +func TestStopReceiver(t *testing.T) { + if client, err := cloudevents.NewHttp("", nil, nil); err != nil { + t.Fatal(err) + } else { + client.StopReceiver() + } +} diff --git a/event/cloudevents/result.go b/event/cloudevents/result.go new file mode 100644 index 0000000..8fedba7 --- /dev/null +++ b/event/cloudevents/result.go @@ -0,0 +1,70 @@ +// Package cloudevents provides cloudevents client and server implementations. +package cloudevents + +import ( + "errors" + + cloudeventssdk "github.com/cloudevents/sdk-go/v2" + "github.com/cloudevents/sdk-go/v2/protocol" + cloudeventssdk_http "github.com/cloudevents/sdk-go/v2/protocol/http" +) + +// NewResult creates and returns a result. +// +// ex) result := cloudevents.NewResult("ok") +func NewResult(format string, arguments ...any) Result { + return Result{result: cloudeventssdk.NewResult(format, arguments)} +} + +// NewResult creates and returns a result. +// +// ex) result := cloudevents.NewHTTPResult(http.StatusOK, "") +func NewHTTPResult(statusCode int, format string, arguments ...any) Result { + return Result{result: cloudeventssdk.NewHTTPResult(statusCode, format, arguments)} +} + +// Result is the result of event delivery. +type Result struct { + result protocol.Result +} + +// IsACK returns whether the recipient acknowledged the event. +// +// ex) isACK := result.IsACK() +func (this *Result) IsACK() bool { + return cloudeventssdk.IsACK(this.result) +} + +// IsNACK returns whether the recipient did not acknowledge the event. +// +// ex) isNACK := result.IsNACK() +func (this *Result) IsNACK() bool { + return cloudeventssdk.IsNACK(this.result) +} + +// IsUndelivered returns whether it was delivered or not. +// +// ex) isUndelivered := result.IsUndelivered() +func (this *Result) IsUndelivered() bool { + return cloudeventssdk.IsUndelivered(this.result) +} + +// GetHttpStatusCode returns the status code if the result is http. +// +// ex) statusCode, err := result.GetHttpStatusCode() +func (this *Result) GetHttpStatusCode() (int, error) { + httpResult := new(cloudeventssdk_http.Result) + + if cloudeventssdk.ResultAs(this.result, &httpResult) == false { + return -1, errors.New("match failed.") + } else { + return httpResult.StatusCode, nil + } +} + +// Error returns the error string. +// +// ex) errString := result.Error() +func (this *Result) Error() string { + return this.result.Error() +} diff --git a/event/cloudevents/server.go b/event/cloudevents/server.go new file mode 100644 index 0000000..6df9c94 --- /dev/null +++ b/event/cloudevents/server.go @@ -0,0 +1,44 @@ +// Package cloudevents provides cloudevents client and server implementations. +package cloudevents + +import ( + "context" + "time" + + cloudeventssdk "github.com/cloudevents/sdk-go/v2" + "github.com/cloudevents/sdk-go/v2/protocol" + "github.com/common-library/go/http" +) + +// Server is a struct that provides server related methods. +type Server struct { + server http.Server +} + +// Start is start the server. +// +// ex) err := server.Start(address, handler, listenAndServeFailureFunc) +func (this *Server) Start(address string, handler func(Event) (*Event, Result), listenAndServeFailureFunc func(error)) error { + finalHandler := func(requestEvent Event) (*Event, protocol.Result) { + responseEvent, result := handler(requestEvent) + return responseEvent, result.result + } + + if protocol, err := cloudeventssdk.NewHTTP(); err != nil { + return err + } else if eventReceiver, err := cloudeventssdk.NewHTTPReceiveHandler(context.Background(), protocol, finalHandler); err != nil { + + return err + } else { + this.server.RegisterPathPrefixHandler("/", eventReceiver) + + return this.server.Start(address, listenAndServeFailureFunc) + } +} + +// Stop is stop the server. +// +// ex) err := server.Stop(10) +func (this *Server) Stop(shutdownTimeout time.Duration) error { + return this.server.Stop(shutdownTimeout) +} diff --git a/event/cloudevents/server_test.go b/event/cloudevents/server_test.go new file mode 100644 index 0000000..ed946a0 --- /dev/null +++ b/event/cloudevents/server_test.go @@ -0,0 +1,35 @@ +package cloudevents_test + +import ( + "net/http" + "testing" + + "github.com/common-library/go/event/cloudevents" +) + +func TestStart(t *testing.T) { + address, server := startServer(t) + defer stopServer(t, server) + + if client, err := cloudevents.NewHttp("http://"+address, nil, nil); err != nil { + t.Fatal(err) + } else { + for i := 0; i < 100; i++ { + if result := client.Send(getEvent(t)); result.IsUndelivered() { + t.Fatal(result.Error()) + } else if statusCode, err := result.GetHttpStatusCode(); err != nil { + t.Fatal(err) + } else if statusCode != http.StatusOK { + t.Fatal("invalid -", statusCode) + } + } + } +} + +func TestStop(t *testing.T) { + server := cloudevents.Server{} + + if err := server.Stop(10); err != nil { + t.Fatal(err) + } +} diff --git a/event/cloudevents/type.go b/event/cloudevents/type.go new file mode 100644 index 0000000..3b08ff0 --- /dev/null +++ b/event/cloudevents/type.go @@ -0,0 +1,10 @@ +// Package cloudevents provides cloudevents client and server implementations. +package cloudevents + +import ( + v2 "github.com/cloudevents/sdk-go/v2" +) + +var NewEvent = v2.NewEvent + +type Event = v2.Event diff --git a/event/cloudevents/type_test.go b/event/cloudevents/type_test.go new file mode 100644 index 0000000..fc4cc16 --- /dev/null +++ b/event/cloudevents/type_test.go @@ -0,0 +1,90 @@ +package cloudevents_test + +import ( + "math/rand/v2" + "net/http" + "strconv" + "testing" + "time" + + cloudeventssdk "github.com/cloudevents/sdk-go/v2" + "github.com/common-library/go/event/cloudevents" +) + +const eventID = "id-01" +const eventType = "type 01" +const eventSource = "source/01" +const eventSubject = "subject 01" +const eventDataContentType = cloudeventssdk.ApplicationJSON +const eventExtensionsName01 = "name01" +const eventExtensionsValue01 = "1" +const eventExtensionsName02 = "name02" +const eventExtensionsValue02 = "value02" +const eventData = `{"id":1,"message":"Hello, World!"}` + +func getEvent(t *testing.T) cloudevents.Event { + event := cloudevents.NewEvent() + event.SetID(eventID) + event.SetTime(time.Now()) + event.SetType(eventType) + event.SetSource(eventSource) + event.SetSubject(eventSubject) + event.SetExtension(eventExtensionsName01, eventExtensionsValue01) + event.SetExtension(eventExtensionsName02, eventExtensionsValue02) + if err := event.SetData(cloudeventssdk.ApplicationJSON, map[string]any{ + "id": 1, + "message": "Hello, World!", + }); err != nil { + t.Fatal(err) + } + + return event +} + +func consistencyEvent(t *testing.T, event *cloudevents.Event) { + if event.ID() != eventID { + t.Error("invalid -", event.ID()) + } else if event.Type() != eventType { + t.Error("invalid -", event.Type()) + } else if event.Source() != eventSource { + t.Error("invalid -", event.Source()) + } else if event.Subject() != eventSubject { + t.Error("invalid -", event.Subject()) + } else if event.DataContentType() != eventDataContentType { + t.Error("invalid -", event.DataContentType()) + } else if event.Extensions()[eventExtensionsName01] == nil || + event.Extensions()[eventExtensionsName01].(string) != eventExtensionsValue01 { + t.Error("invalid -", event.Extensions()[eventExtensionsName01]) + } else if event.Extensions()[eventExtensionsName02] == nil || + event.Extensions()[eventExtensionsName02].(string) != eventExtensionsValue02 { + t.Error("invalid -", event.Extensions()[eventExtensionsName02]) + } else if string(event.Data()) != eventData { + t.Error("invalid -", string(event.Data())) + } +} + +func startServer(t *testing.T) (string, *cloudevents.Server) { + handler := func(event cloudevents.Event) (*cloudevents.Event, cloudevents.Result) { + consistencyEvent(t, &event) + + responseEvent := event.Clone() + return &responseEvent, cloudevents.NewHTTPResult(http.StatusOK, "") + } + + address := ":" + strconv.Itoa(10000+rand.IntN(1000)) + listenAndServeFailureFunc := func(err error) { t.Fatal(err) } + + server := cloudevents.Server{} + if err := server.Start(address, handler, listenAndServeFailureFunc); err != nil { + t.Fatal(err) + } + time.Sleep(200 * time.Millisecond) + + return address, &server +} + +func stopServer(t *testing.T, server *cloudevents.Server) { + if err := server.Stop(10); err != nil { + t.Fatal(err) + } +} diff --git a/go.mod b/go.mod index 85212d5..7b8eb97 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/dynamodb v1.31.1 github.com/aws/aws-sdk-go-v2/service/s3 v1.53.1 github.com/btnguyen2k/godynamo v1.2.1 + github.com/cloudevents/sdk-go/v2 v2.15.2 github.com/elastic/elastic-transport-go/v8 v8.5.0 github.com/elastic/go-elasticsearch/v7 v7.17.10 github.com/elastic/go-elasticsearch/v8 v8.13.1 @@ -115,6 +116,9 @@ require ( go.opentelemetry.io/otel v1.25.0 // indirect go.opentelemetry.io/otel/metric v1.25.0 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.19.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/go.sum b/go.sum index 98ea014..1839f9d 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 h1:cwIxeBttqPN3qkaAjcEcsh8NYr8n github.com/aws/aws-sdk-go-v2/service/sts v1.28.6/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/btnguyen2k/consu/g18 v0.1.0 h1:IoS5w5QlOfkcrNOHJyICD6PgqLh+J5fIDqy3vRBVcVM= @@ -82,6 +84,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/sdk-go/v2 v2.15.2 h1:54+I5xQEnI73RBhWHxbI1XJcqOFOVJN85vb41+8mHUc= +github.com/cloudevents/sdk-go/v2 v2.15.2/go.mod h1:lL7kSWAE/V8VI4Wh0jbL2v/jvqsm6tjmaQBSvxcv4uE= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 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= @@ -197,8 +201,11 @@ github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= @@ -232,6 +239,9 @@ github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= @@ -255,6 +265,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -262,6 +274,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0= github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= @@ -289,6 +303,16 @@ go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -300,6 +324,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -355,6 +381,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -395,16 +422,19 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=