From 3ca70334a044bad0fb21049ee33e874e07b491ed Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 29 Apr 2022 16:14:04 +0800 Subject: [PATCH] simplify WrapHandler --- dtmcli/types.go | 16 ++++++++++++++ dtmutil/utils.go | 18 ++++++++++++++++ test/busi/barrier.go | 46 ++++++++++++++++++++-------------------- test/busi/base_http.go | 34 ++++++++++++++--------------- test/busi/base_jrpc.go | 2 +- test/tcc_barrier_test.go | 3 +-- 6 files changed, 76 insertions(+), 43 deletions(-) diff --git a/dtmcli/types.go b/dtmcli/types.go index f48e30f..8e45478 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -7,7 +7,9 @@ package dtmcli import ( + "errors" "fmt" + "net/http" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/go-resty/resty/v2" @@ -79,3 +81,17 @@ func GetRestyClient() *resty.Client { func SetPassthroughHeaders(headers []string) { dtmimp.PassthroughHeaders = headers } + +// Result2HttpCode return the http code for the result +// if result is error, the return proper code, else return StatusOK +func Result2HttpCode(result interface{}) int { + err, _ := result.(error) + if errors.Is(err, ErrFailure) { + return http.StatusConflict + } else if errors.Is(err, ErrOngoing) { + return http.StatusTooEarly + } else if err != nil { + return http.StatusInternalServerError + } + return http.StatusOK +} diff --git a/dtmutil/utils.go b/dtmutil/utils.go index 9c78bb2..82830e9 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -47,7 +47,25 @@ func GetGinApp() *gin.Engine { return app } +// WrapHandler used by examples. much more simpler than WrapHandler2 +func WrapHandler(fn func(*gin.Context) interface{}) gin.HandlerFunc { + return func(c *gin.Context) { + began := time.Now() + ret := fn(c) + status := dtmcli.Result2HttpCode(ret) + + b, _ := json.Marshal(ret) + if status == http.StatusOK || status == http.StatusTooEarly { + logger.Infof("%2dms %d %s %s %s", time.Since(began).Milliseconds(), status, c.Request.Method, c.Request.RequestURI, string(b)) + } else { + logger.Errorf("%2dms %d %s %s %s", time.Since(began).Milliseconds(), status, c.Request.Method, c.Request.RequestURI, string(b)) + } + c.JSON(status, ret) + } +} + // WrapHandler2 wrap a function te bo the handler of gin request +// used by dtmsvr func WrapHandler2(fn func(*gin.Context) interface{}) gin.HandlerFunc { return func(c *gin.Context) { began := time.Now() diff --git a/test/busi/barrier.go b/test/busi/barrier.go index 7937dbe..69c7c07 100644 --- a/test/busi/barrier.go +++ b/test/busi/barrier.go @@ -20,19 +20,19 @@ import ( func init() { setupFuncs["BarrierSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/SagaBTransInCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaBTransInCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaB2TransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaB2TransIn", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) err := barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount/2, reqFrom(c).TransInResult) @@ -44,7 +44,7 @@ func init() { return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount/2, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/SagaB2TransInCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaB2TransInCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) err := barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount/2, "") @@ -56,19 +56,19 @@ func init() { return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) }) })) - app.POST(BusiAPI+"/SagaBTransOutCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaBTransOutCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransOutUID, reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { req := reqFrom(c) barrier := MustBarrierFromGin(c) tx := dbGet().DB.Begin() @@ -77,7 +77,7 @@ func init() { }) })) - app.POST(BusiAPI+"/TccBTransInTry", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TccBTransInTry", dtmutil.WrapHandler(func(c *gin.Context) interface{} { req := reqFrom(c) if req.TransInResult != "" { return dtmcli.String2DtmError(req.TransInResult) @@ -86,17 +86,17 @@ func init() { return tccAdjustTrading(tx, TransInUID, req.Amount) }) })) - app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustBalance(tx, TransInUID, reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransInUID, -reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/SagaMultiSource", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMultiSource", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) transOutSource := pdbGet() err := barrier.CallWithDB(transOutSource, func(tx *sql.Tx) error { @@ -110,7 +110,7 @@ func init() { return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/SagaMultiSourceRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMultiSourceRevert", dtmutil.WrapHandler(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) transOutSource := pdbGet() err := barrier.CallWithDB(transOutSource, func(tx *sql.Tx) error { @@ -124,39 +124,39 @@ func init() { return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaRedisTransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaRedisTransIn", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), GetRedisAccountKey(TransInUID), reqFrom(c).Amount, 7*86400) })) - app.POST(BusiAPI+"/SagaRedisTransInCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaRedisTransInCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), GetRedisAccountKey(TransInUID), -reqFrom(c).Amount, 7*86400) })) - app.POST(BusiAPI+"/SagaRedisTransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaRedisTransOut", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), GetRedisAccountKey(TransOutUID), -reqFrom(c).Amount, 7*86400) })) - app.POST(BusiAPI+"/SagaRedisTransOutCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaRedisTransOutCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), GetRedisAccountKey(TransOutUID), reqFrom(c).Amount, 7*86400) })) - app.POST(BusiAPI+"/SagaMongoTransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMongoTransIn", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).MongoCall(MongoGet(), func(sc mongo.SessionContext) error { return SagaMongoAdjustBalance(sc, sc.Client(), TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/SagaMongoTransInCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMongoTransInCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).MongoCall(MongoGet(), func(sc mongo.SessionContext) error { return SagaMongoAdjustBalance(sc, sc.Client(), TransInUID, -reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaMongoTransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMongoTransOut", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).MongoCall(MongoGet(), func(sc mongo.SessionContext) error { return SagaMongoAdjustBalance(sc, sc.Client(), TransOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) }) })) - app.POST(BusiAPI+"/SagaMongoTransOutCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SagaMongoTransOutCom", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return MustBarrierFromGin(c).MongoCall(MongoGet(), func(sc mongo.SessionContext) error { return SagaMongoAdjustBalance(sc, sc.Client(), TransOutUID, reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler(func(c *gin.Context) interface{} { req := reqFrom(c) if req.TransOutResult != "" { return dtmcli.String2DtmError(req.TransOutResult) @@ -174,7 +174,7 @@ func init() { return tccAdjustTrading(tx, TransOutUID, -req.Amount) }) })) - app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { if reqFrom(c).Store == Redis || reqFrom(c).Store == Mongo { return nil } @@ -182,7 +182,7 @@ func init() { return tccAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler2(TccBarrierTransOutCancel)) + app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler(TccBarrierTransOutCancel)) } } diff --git a/test/busi/base_http.go b/test/busi/base_http.go index 6018e69..e2609bf 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -76,22 +76,22 @@ func BaseAppStartup() *gin.Engine { // BaseAddRoute add base route handler func BaseAddRoute(app *gin.Engine) { - app.POST(BusiAPI+"/TransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInResult.Fetch(), reqFrom(c).TransInResult, "transIn") })) - app.POST(BusiAPI+"/TransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransInConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInConfirmResult.Fetch(), "", "TransInConfirm") })) - app.POST(BusiAPI+"/TransOutConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutConfirmResult.Fetch(), "", "TransOutConfirm") })) - app.POST(BusiAPI+"/TransInRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransInRevert", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInRevertResult.Fetch(), "", "TransInRevert") })) - app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) app.POST(BusiAPI+"/TransInOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { @@ -113,37 +113,37 @@ func BaseAddRoute(app *gin.Engine) { return handleGeneralBusinessCompatible(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) - app.GET(BusiAPI+"/QueryPrepared", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.GET(BusiAPI+"/QueryPrepared", dtmutil.WrapHandler(func(c *gin.Context) interface{} { logger.Debugf("%s QueryPrepared", c.Query("gid")) return dtmcli.String2DtmError(dtmimp.OrString(MainSwitch.QueryPreparedResult.Fetch(), dtmcli.ResultSuccess)) })) - app.GET(BusiAPI+"/QueryPreparedB", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.GET(BusiAPI+"/QueryPreparedB", dtmutil.WrapHandler(func(c *gin.Context) interface{} { logger.Debugf("%s QueryPreparedB", c.Query("gid")) bb := MustBarrierFromGin(c) db := dbGet().ToSQLDB() return bb.QueryPrepared(db) })) - app.GET(BusiAPI+"/RedisQueryPrepared", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.GET(BusiAPI+"/RedisQueryPrepared", dtmutil.WrapHandler(func(c *gin.Context) interface{} { logger.Debugf("%s RedisQueryPrepared", c.Query("gid")) bb := MustBarrierFromGin(c) return bb.RedisQueryPrepared(RedisGet(), 86400) })) - app.GET(BusiAPI+"/MongoQueryPrepared", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.GET(BusiAPI+"/MongoQueryPrepared", dtmutil.WrapHandler(func(c *gin.Context) interface{} { logger.Debugf("%s MongoQueryPrepared", c.Query("gid")) bb := MustBarrierFromGin(c) return bb.MongoQueryPrepared(MongoGet()) })) - app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return dtmcli.XaLocalTransaction(c.Request.URL.Query(), BusiConf, func(db *sql.DB, xa *dtmcli.Xa) error { return SagaAdjustBalance(db, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return dtmcli.XaLocalTransaction(c.Request.URL.Query(), BusiConf, func(db *sql.DB, xa *dtmcli.Xa) error { return SagaAdjustBalance(db, TransOutUID, reqFrom(c).Amount, reqFrom(c).TransOutResult) }) })) - app.POST(BusiAPI+"/TransOutTimeout", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutTimeout", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) app.POST(BusiAPI+"/TransInTccNested", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { @@ -156,7 +156,7 @@ func BaseAddRoute(app *gin.Engine) { } return resp })) - app.POST(BusiAPI+"/TransOutXaGorm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutXaGorm", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return dtmcli.XaLocalTransaction(c.Request.URL.Query(), BusiConf, func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransOutResult == dtmcli.ResultFailure { return dtmcli.ErrFailure @@ -184,17 +184,17 @@ func BaseAddRoute(app *gin.Engine) { } return nil })) - app.POST(BusiAPI+"/SleepCancel", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/SleepCancel", dtmutil.WrapHandler(func(c *gin.Context) interface{} { return sleepCancelHandler(c) })) - app.POST(BusiAPI+"/TransOutHeaderYes", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutHeaderYes", dtmutil.WrapHandler(func(c *gin.Context) interface{} { h := c.GetHeader("test_header") if h == "" { return errors.New("no test_header found in TransOutHeaderYes") } return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransOutHeaderNo", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransOutHeaderNo", dtmutil.WrapHandler(func(c *gin.Context) interface{} { h := c.GetHeader("test_header") if h != "" { return errors.New("test_header found in TransOutHeaderNo") diff --git a/test/busi/base_jrpc.go b/test/busi/base_jrpc.go index 56ec9e9..8378790 100644 --- a/test/busi/base_jrpc.go +++ b/test/busi/base_jrpc.go @@ -13,7 +13,7 @@ import ( var BusiJrpcURL = fmt.Sprintf("http://localhost:%d/api/json-rpc?method=", BusiPort) func addJrpcRoute(app *gin.Engine) { - app.POST("/api/json-rpc", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST("/api/json-rpc", dtmutil.WrapHandler(func(c *gin.Context) interface{} { var data map[string]interface{} err := c.BindJSON(&data) dtmimp.E2P(err) diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index bbafb2a..fb2beef 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -10,7 +10,6 @@ import ( "context" "database/sql" "fmt" - "strings" "testing" "github.com/dtm-labs/dtm/dtmcli" @@ -124,7 +123,7 @@ func runTestTccBarrierDisorder(t *testing.T, store string) { "op": dtmimp.OpTry, }). Post(tryURL) - assert.True(t, strings.Contains(r.String(), dtmcli.ResultSuccess)) // dangle op, return success + assert.Equal(t, r.StatusCode(), 200) // dangle op, return success logger.Debugf("cronFinished read") <-cronFinished <-cronFinished