diff --git a/go.mod b/go.mod index ce37e972..626546b1 100644 --- a/go.mod +++ b/go.mod @@ -56,6 +56,8 @@ require ( require ( cloud.google.com/go/pubsub v1.30.0 + github.com/goccy/go-json v0.10.2 + github.com/json-iterator/go v1.1.12 github.com/newrelic/go-agent v2.1.0+incompatible gorm.io/driver/mysql v1.4.5 gorm.io/driver/postgres v1.4.6 @@ -111,6 +113,8 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index a875862d..8b1e4977 100644 --- a/go.sum +++ b/go.sum @@ -174,6 +174,8 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gohttp/pprof v0.0.0-20141119085724-c9d246cbb3ba h1:OckY4Dk1WhEEEz4zYYMsXG5f6necMtGAyAs19vcpRXk= github.com/gohttp/pprof v0.0.0-20141119085724-c9d246cbb3ba/go.mod h1:V97TX7IXWIioKfmy0IKnnBzsC1jRXP2VicslN9O8IIQ= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -213,6 +215,7 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -278,6 +281,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= @@ -313,6 +318,11 @@ github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/newrelic/go-agent v2.1.0+incompatible h1:fCuxXeM4eeIKPbzffOWW6y2Dj+eYfc3yylgNZACZqkM= github.com/newrelic/go-agent v2.1.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ= diff --git a/pkg/entity/flag_snapshot.go b/pkg/entity/flag_snapshot.go index adab8cd4..30e527b3 100644 --- a/pkg/entity/flag_snapshot.go +++ b/pkg/entity/flag_snapshot.go @@ -1,9 +1,8 @@ package entity import ( - "encoding/json" "fmt" - + jsoniter "github.com/json-iterator/go" "github.com/openflagr/flagr/pkg/config" "github.com/openflagr/flagr/pkg/util" "github.com/sirupsen/logrus" @@ -21,6 +20,8 @@ type FlagSnapshot struct { // SaveFlagSnapshot saves the Flag Snapshot func SaveFlagSnapshot(db *gorm.DB, flagID uint, updatedBy string) { + var json = jsoniter.ConfigFastest + tx := db.Begin() f := &Flag{} if err := tx.First(f, flagID).Error; err != nil { diff --git a/pkg/entity/variant.go b/pkg/entity/variant.go index beb5ed5c..de23e8d5 100644 --- a/pkg/entity/variant.go +++ b/pkg/entity/variant.go @@ -2,8 +2,8 @@ package entity import ( "database/sql/driver" - "encoding/json" "fmt" + jsoniter "github.com/json-iterator/go" "github.com/openflagr/flagr/pkg/util" "github.com/spf13/cast" @@ -32,6 +32,8 @@ type Attachment map[string]interface{} // Scan implements scanner interface func (a *Attachment) Scan(value interface{}) error { + var json = jsoniter.ConfigFastest + if value == nil { return nil } @@ -44,6 +46,8 @@ func (a *Attachment) Scan(value interface{}) error { // Value implements valuer interface func (a Attachment) Value() (driver.Value, error) { + var json = jsoniter.ConfigFastest + bytes, err := json.Marshal(a) if err != nil { return nil, err diff --git a/pkg/handler/crud_test.go b/pkg/handler/crud_test.go index 571bdbe7..ee180682 100644 --- a/pkg/handler/crud_test.go +++ b/pkg/handler/crud_test.go @@ -1,8 +1,8 @@ package handler import ( - "encoding/json" "fmt" + jsoniter "github.com/json-iterator/go" "testing" "github.com/openflagr/flagr/pkg/entity" @@ -464,6 +464,8 @@ func TestFindFlags(t *testing.T) { } func TestGetFlagSnapshots(t *testing.T) { + var json = jsoniter.ConfigFastest + var res middleware.Responder db := entity.NewTestDB() c := &crud{} diff --git a/pkg/handler/data_record_frame.go b/pkg/handler/data_record_frame.go index feb74943..f52ef9e7 100644 --- a/pkg/handler/data_record_frame.go +++ b/pkg/handler/data_record_frame.go @@ -3,8 +3,9 @@ package handler import ( "encoding/base64" "encoding/json" - "github.com/brandur/simplebox" + + jsoniter "github.com/json-iterator/go" "github.com/openflagr/flagr/pkg/util" "github.com/openflagr/flagr/swagger_gen/models" ) @@ -56,6 +57,8 @@ type DataRecordFrame struct { // MarshalJSON defines the behavior of MarshalJSON for DataRecordFrame func (drf *DataRecordFrame) MarshalJSON() ([]byte, error) { + var json = jsoniter.ConfigFastest + payload, err := drf.evalResult.MarshalBinary() if err != nil { return nil, err @@ -94,5 +97,6 @@ func (drf *DataRecordFrame) GetPartitionKey() string { // Output sets the paylaod using its input and returns the json marshal bytes func (drf *DataRecordFrame) Output() ([]byte, error) { + var json = jsoniter.ConfigFastest return json.Marshal(drf) } diff --git a/pkg/handler/eval.go b/pkg/handler/eval.go index 79b4e7fb..a0a0283b 100644 --- a/pkg/handler/eval.go +++ b/pkg/handler/eval.go @@ -1,8 +1,8 @@ package handler import ( - "encoding/json" "fmt" + jsoniter "github.com/json-iterator/go" "math/rand" "sync" "time" @@ -318,6 +318,7 @@ func debugConstraintMsg(enableDebug bool, expr conditions.Expr, m map[string]int var rateLimitMap = sync.Map{} var rateLimitPerFlagConsoleLogging = func(r *models.EvalResult) { + var json = jsoniter.ConfigFastest flagID := util.SafeUint(r.FlagID) rl, _ := rateLimitMap.LoadOrStore(flagID, ratelimit.New( config.Config.RateLimiterPerFlagPerSecondConsoleLogging, diff --git a/pkg/handler/eval_cache_fetcher.go b/pkg/handler/eval_cache_fetcher.go index 212ffe21..60eada70 100644 --- a/pkg/handler/eval_cache_fetcher.go +++ b/pkg/handler/eval_cache_fetcher.go @@ -1,8 +1,8 @@ package handler import ( - "encoding/json" "fmt" + jsoniter "github.com/json-iterator/go" "io" "net/http" "os" @@ -97,6 +97,8 @@ type jsonFileFetcher struct { } func (ff *jsonFileFetcher) fetch() ([]entity.Flag, error) { + var json = jsoniter.ConfigFastest + b, err := os.ReadFile(ff.filePath) if err != nil { return nil, err @@ -114,6 +116,8 @@ type jsonHTTPFetcher struct { } func (hf *jsonHTTPFetcher) fetch() ([]entity.Flag, error) { + var json = jsoniter.ConfigFastest + client := http.Client{Timeout: config.Config.EvalCacheRefreshTimeout} res, err := client.Get(hf.url) if err != nil { diff --git a/pkg/mapper/entity_restapi/e2r/e2r.go b/pkg/mapper/entity_restapi/e2r/e2r.go index 1c771c97..b7c3409b 100644 --- a/pkg/mapper/entity_restapi/e2r/e2r.go +++ b/pkg/mapper/entity_restapi/e2r/e2r.go @@ -1,7 +1,7 @@ package e2r import ( - "encoding/json" + jsoniter "github.com/json-iterator/go" "time" "github.com/go-openapi/strfmt" @@ -46,6 +46,7 @@ func MapFlags(e []entity.Flag) ([]*models.Flag, error) { // MapFlagSnapshot maps flag snapshot func MapFlagSnapshot(e *entity.FlagSnapshot) (*models.FlagSnapshot, error) { + var json = jsoniter.ConfigFastest ef := &entity.Flag{} if err := json.Unmarshal(e.Flag, ef); err != nil { return nil, err diff --git a/swagger_gen/restapi/configure_flagr.go b/swagger_gen/restapi/configure_flagr.go index 7d10af27..f29802cd 100644 --- a/swagger_gen/restapi/configure_flagr.go +++ b/swagger_gen/restapi/configure_flagr.go @@ -4,7 +4,9 @@ package restapi import ( "crypto/tls" + jsoniter "github.com/json-iterator/go" "net/http" + "io" "github.com/openflagr/flagr/pkg/config" "github.com/openflagr/flagr/pkg/handler" @@ -26,8 +28,19 @@ func configureFlags(api *operations.FlagrAPI) { func configureAPI(api *operations.FlagrAPI) http.Handler { api.ServeError = errors.ServeError - api.JSONConsumer = runtime.JSONConsumer() - api.JSONProducer = runtime.JSONProducer() + api.JSONConsumer = runtime.ConsumerFunc(func(reader io.Reader, data interface{}) error { + json := jsoniter.ConfigFastest + dec := json.NewDecoder(reader) + dec.UseNumber() + return dec.Decode(data) + }) + + api.JSONProducer = runtime.ProducerFunc(func(writer io.Writer, data interface{}) error { + json := jsoniter.ConfigFastest + enc := json.NewEncoder(writer) + enc.SetEscapeHTML(false) + return enc.Encode(data) + }) api.BinProducer = runtime.ByteStreamProducer() api.Logger = logrus.Infof