OSDN Git Service

refactor toolbar/server (#390)
authorHAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Wed, 28 Aug 2019 16:51:02 +0000 (00:51 +0800)
committerPaladz <yzhu101@uottawa.ca>
Wed, 28 Aug 2019 16:51:02 +0000 (00:51 +0800)
* migrate

* rename

toolbar/federation/api/handler.go
toolbar/federation/api/server.go
toolbar/server/common.go [moved from toolbar/federation/api/common.go with 95% similarity]
toolbar/server/display.go [moved from toolbar/federation/api/display.go with 98% similarity]
toolbar/server/errors.go [moved from toolbar/federation/api/errors.go with 96% similarity]
toolbar/server/handle.go [new file with mode: 0644]
toolbar/server/pagination.go [moved from toolbar/federation/api/pagination.go with 99% similarity]
toolbar/server/response.go [moved from toolbar/federation/api/response.go with 99% similarity]

index d8f1445..8a23b9f 100644 (file)
@@ -10,11 +10,12 @@ import (
        "github.com/vapor/errors"
        "github.com/vapor/toolbar/federation/common"
        "github.com/vapor/toolbar/federation/database/orm"
        "github.com/vapor/errors"
        "github.com/vapor/toolbar/federation/common"
        "github.com/vapor/toolbar/federation/database/orm"
+       serverCommon "github.com/vapor/toolbar/server"
 )
 
 )
 
-type listCrosschainTxsReq struct{ Display }
+type listCrosschainTxsReq struct{ serverCommon.Display }
 
 
-func (s *Server) ListCrosschainTxs(c *gin.Context, listTxsReq *listCrosschainTxsReq, query *PaginationQuery) ([]*orm.CrossTransaction, error) {
+func (s *Server) ListCrosschainTxs(c *gin.Context, listTxsReq *listCrosschainTxsReq, query *serverCommon.PaginationQuery) ([]*orm.CrossTransaction, error) {
        var ormTxs []*orm.CrossTransaction
        txFilter := &orm.CrossTransaction{}
 
        var ormTxs []*orm.CrossTransaction
        txFilter := &orm.CrossTransaction{}
 
index 2aff662..3df3925 100644 (file)
@@ -1,16 +1,11 @@
 package api
 
 import (
 package api
 
 import (
-       "encoding/json"
-       "net/http"
-       "reflect"
-       "strings"
-
        "github.com/gin-gonic/gin"
        "github.com/jinzhu/gorm"
 
        "github.com/gin-gonic/gin"
        "github.com/jinzhu/gorm"
 
-       "github.com/vapor/errors"
        "github.com/vapor/toolbar/federation/config"
        "github.com/vapor/toolbar/federation/config"
+       serverCommon "github.com/vapor/toolbar/server"
 )
 
 type Server struct {
 )
 
 type Server struct {
@@ -31,201 +26,17 @@ func NewServer(db *gorm.DB, cfg *config.Config) *Server {
        return server
 }
 
        return server
 }
 
-func (server *Server) setupRouter() {
+func (s *Server) setupRouter() {
        r := gin.Default()
        r := gin.Default()
-       r.Use(server.middleware())
+       r.Use(serverCommon.Middleware(s))
 
        v1 := r.Group("/api/v1")
 
        v1 := r.Group("/api/v1")
-       v1.POST("/federation/list-crosschain-txs", handlerMiddleware(server.ListCrosschainTxs))
-       v1.GET("/federation/list-chains", handlerMiddleware(server.ListChains))
+       v1.POST("/federation/list-crosschain-txs", serverCommon.HandlerMiddleware(s.ListCrosschainTxs))
+       v1.GET("/federation/list-chains", serverCommon.HandlerMiddleware(s.ListChains))
 
 
-       server.engine = r
+       s.engine = r
 }
 
 func (s *Server) Run() {
        s.engine.Run(":9886")
 }
 }
 
 func (s *Server) Run() {
        s.engine.Run(":9886")
 }
-
-func (s *Server) middleware() gin.HandlerFunc {
-       return func(c *gin.Context) {
-               // add Access-Control-Allow-Origin
-               c.Header("Access-Control-Allow-Origin", "*")
-               c.Header("Access-Control-Allow-Headers", "Content-Type")
-               c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
-               if c.Request.Method == "OPTIONS" {
-                       c.AbortWithStatus(http.StatusOK)
-                       return
-               }
-
-               c.Set(serverLabel, s)
-               c.Next()
-       }
-}
-
-type handlerFun interface{}
-
-func handlerMiddleware(handleFunc interface{}) func(*gin.Context) {
-       if err := validateFuncType(handleFunc); err != nil {
-               panic(err)
-       }
-
-       return func(context *gin.Context) {
-               handleRequest(context, handleFunc)
-       }
-}
-
-func validateFuncType(fun handlerFun) error {
-       ft := reflect.TypeOf(fun)
-       if ft.Kind() != reflect.Func || ft.IsVariadic() {
-               return errors.New("need nonvariadic func in " + ft.String())
-       }
-
-       if ft.NumIn() < 1 || ft.NumIn() > 3 {
-               return errors.New("need one or two or three parameters in " + ft.String())
-       }
-
-       if ft.In(0) != contextType {
-               return errors.New("the first parameter must point of context in " + ft.String())
-       }
-
-       if ft.NumIn() == 2 && ft.In(1).Kind() != reflect.Ptr {
-               return errors.New("the second parameter must point in " + ft.String())
-       }
-
-       if ft.NumIn() == 3 && ft.In(2) != paginationQueryType {
-               return errors.New("the third parameter of pagination must point of paginationQuery in " + ft.String())
-       }
-
-       if ft.NumOut() < 1 || ft.NumOut() > 2 {
-               return errors.New("the size of return value must one or two in " + ft.String())
-       }
-
-       // if has pagination, the first return value must slice or array
-       if ft.NumIn() == 3 && ft.Out(0).Kind() != reflect.Slice && ft.Out(0).Kind() != reflect.Array {
-               return errors.New("the first return value of pagination must slice of array in " + ft.String())
-       }
-
-       if !ft.Out(ft.NumOut() - 1).Implements(errorType) {
-               return errors.New("the last return value must error in " + ft.String())
-       }
-       return nil
-}
-
-// handleRequest get a handler function to process the request by request url
-func handleRequest(context *gin.Context, fun handlerFun) {
-       args, err := buildHandleFuncArgs(fun, context)
-       if err != nil {
-               respondErrorResp(context, err)
-               return
-       }
-
-       result := callHandleFunc(fun, args...)
-       if err := result[len(result)-1]; err != nil {
-               respondErrorResp(context, err.(error))
-               return
-       }
-
-       if exist := processPaginationIfPresent(fun, args, result, context); exist {
-               return
-       }
-
-       if len(result) == 1 {
-               respondSuccessResp(context, nil)
-               return
-       }
-
-       respondSuccessResp(context, result[0])
-}
-
-func buildHandleFuncArgs(fun handlerFun, context *gin.Context) ([]interface{}, error) {
-       args := []interface{}{context}
-
-       req, err := createHandleReqArg(fun, context)
-       if err != nil {
-               return nil, errors.Wrap(err, "createHandleReqArg")
-       }
-
-       if err := checkDisplayOrder(req); err != nil {
-               return nil, err
-       }
-
-       if req != nil {
-               args = append(args, req)
-       }
-
-       ft := reflect.TypeOf(fun)
-
-       // no pagination exists
-       if ft.NumIn() != 3 {
-               return args, nil
-       }
-
-       query, err := parsePagination(context)
-       if err != nil {
-               return nil, errors.Wrap(err, "ParsePagination")
-       }
-
-       args = append(args, query)
-       return args, nil
-}
-
-func createHandleReqArg(fun handlerFun, context *gin.Context) (interface{}, error) {
-       ft := reflect.TypeOf(fun)
-       if ft.NumIn() == 1 {
-               return nil, nil
-       }
-       argType := ft.In(1).Elem()
-
-       reqArg := reflect.New(argType).Interface()
-       if err := context.ShouldBindJSON(reqArg); err != nil {
-               return nil, errors.Wrap(err, "bind reqArg")
-       }
-
-       b, err := json.Marshal(reqArg)
-       if err != nil {
-               return nil, errors.Wrap(err, "json marshal")
-       }
-
-       context.Set(reqBodyLabel, string(b))
-
-       return reqArg, nil
-}
-
-func checkDisplayOrder(req interface{}) error {
-       if req == nil {
-               return nil
-       }
-
-       reqType := reflect.TypeOf(req).Elem()
-       reqVal := reflect.ValueOf(req).Elem()
-
-       for i := 0; i < reqType.NumField(); i++ {
-               field := reqType.Field(i)
-               if field.Type != reflect.TypeOf(Display{}) {
-                       continue
-               }
-               display := reqVal.Field(i).Interface().(Display)
-
-               order := strings.Trim(display.Sorter.Order, "")
-               if order != "desc" && order != "asc" {
-                       reqVal.Field(i).Set(reflect.ValueOf(Display{Filter: display.Filter, Sorter: Sorter{By: display.Sorter.By, Order: "desc"}}))
-               }
-       }
-       return nil
-}
-
-func callHandleFunc(fun handlerFun, args ...interface{}) []interface{} {
-       fv := reflect.ValueOf(fun)
-
-       params := make([]reflect.Value, len(args))
-       for i, arg := range args {
-               params[i] = reflect.ValueOf(arg)
-       }
-
-       rs := fv.Call(params)
-       result := make([]interface{}, len(rs))
-       for i, r := range rs {
-               result[i] = r.Interface()
-       }
-       return result
-}
similarity index 95%
rename from toolbar/federation/api/common.go
rename to toolbar/server/common.go
index 161667a..f3122d3 100644 (file)
@@ -1,4 +1,4 @@
-package api
+package server
 
 import (
        "reflect"
 
 import (
        "reflect"
similarity index 98%
rename from toolbar/federation/api/display.go
rename to toolbar/server/display.go
index fed1506..caa4e56 100644 (file)
@@ -1,4 +1,4 @@
-package api
+package server
 
 import (
        "github.com/vapor/errors"
 
 import (
        "github.com/vapor/errors"
similarity index 96%
rename from toolbar/federation/api/errors.go
rename to toolbar/server/errors.go
index f216325..8ecfdfb 100644 (file)
@@ -1,4 +1,4 @@
-package api
+package server
 
 import (
        "github.com/vapor/errors"
 
 import (
        "github.com/vapor/errors"
diff --git a/toolbar/server/handle.go b/toolbar/server/handle.go
new file mode 100644 (file)
index 0000000..b891556
--- /dev/null
@@ -0,0 +1,196 @@
+package server
+
+import (
+       "encoding/json"
+       "net/http"
+       "reflect"
+       "strings"
+
+       "github.com/gin-gonic/gin"
+
+       "github.com/vapor/errors"
+)
+
+func Middleware(serverInstance interface{}) gin.HandlerFunc {
+       return func(c *gin.Context) {
+               // add Access-Control-Allow-Origin
+               c.Header("Access-Control-Allow-Origin", "*")
+               c.Header("Access-Control-Allow-Headers", "Content-Type")
+               c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
+               if c.Request.Method == "OPTIONS" {
+                       c.AbortWithStatus(http.StatusOK)
+                       return
+               }
+
+               c.Set(serverLabel, serverInstance)
+               c.Next()
+       }
+}
+
+type handlerFun interface{}
+
+func HandlerMiddleware(handleFunc interface{}) func(*gin.Context) {
+       if err := validateFuncType(handleFunc); err != nil {
+               panic(err)
+       }
+
+       return func(context *gin.Context) {
+               handleRequest(context, handleFunc)
+       }
+}
+
+func validateFuncType(fun handlerFun) error {
+       ft := reflect.TypeOf(fun)
+       if ft.Kind() != reflect.Func || ft.IsVariadic() {
+               return errors.New("need nonvariadic func in " + ft.String())
+       }
+
+       if ft.NumIn() < 1 || ft.NumIn() > 3 {
+               return errors.New("need one or two or three parameters in " + ft.String())
+       }
+
+       if ft.In(0) != contextType {
+               return errors.New("the first parameter must point of context in " + ft.String())
+       }
+
+       if ft.NumIn() == 2 && ft.In(1).Kind() != reflect.Ptr {
+               return errors.New("the second parameter must point in " + ft.String())
+       }
+
+       if ft.NumIn() == 3 && ft.In(2) != paginationQueryType {
+               return errors.New("the third parameter of pagination must point of paginationQuery in " + ft.String())
+       }
+
+       if ft.NumOut() < 1 || ft.NumOut() > 2 {
+               return errors.New("the size of return value must one or two in " + ft.String())
+       }
+
+       // if has pagination, the first return value must slice or array
+       if ft.NumIn() == 3 && ft.Out(0).Kind() != reflect.Slice && ft.Out(0).Kind() != reflect.Array {
+               return errors.New("the first return value of pagination must slice of array in " + ft.String())
+       }
+
+       if !ft.Out(ft.NumOut() - 1).Implements(errorType) {
+               return errors.New("the last return value must error in " + ft.String())
+       }
+       return nil
+}
+
+// handleRequest get a handler function to process the request by request url
+func handleRequest(context *gin.Context, fun handlerFun) {
+       args, err := buildHandleFuncArgs(fun, context)
+       if err != nil {
+               respondErrorResp(context, err)
+               return
+       }
+
+       result := callHandleFunc(fun, args...)
+       if err := result[len(result)-1]; err != nil {
+               respondErrorResp(context, err.(error))
+               return
+       }
+
+       if exist := processPaginationIfPresent(fun, args, result, context); exist {
+               return
+       }
+
+       if len(result) == 1 {
+               respondSuccessResp(context, nil)
+               return
+       }
+
+       respondSuccessResp(context, result[0])
+}
+
+func buildHandleFuncArgs(fun handlerFun, context *gin.Context) ([]interface{}, error) {
+       args := []interface{}{context}
+
+       req, err := createHandleReqArg(fun, context)
+       if err != nil {
+               return nil, errors.Wrap(err, "createHandleReqArg")
+       }
+
+       if err := checkDisplayOrder(req); err != nil {
+               return nil, err
+       }
+
+       if req != nil {
+               args = append(args, req)
+       }
+
+       ft := reflect.TypeOf(fun)
+
+       // no pagination exists
+       if ft.NumIn() != 3 {
+               return args, nil
+       }
+
+       query, err := parsePagination(context)
+       if err != nil {
+               return nil, errors.Wrap(err, "ParsePagination")
+       }
+
+       args = append(args, query)
+       return args, nil
+}
+
+func createHandleReqArg(fun handlerFun, context *gin.Context) (interface{}, error) {
+       ft := reflect.TypeOf(fun)
+       if ft.NumIn() == 1 {
+               return nil, nil
+       }
+       argType := ft.In(1).Elem()
+
+       reqArg := reflect.New(argType).Interface()
+       if err := context.ShouldBindJSON(reqArg); err != nil {
+               return nil, errors.Wrap(err, "bind reqArg")
+       }
+
+       b, err := json.Marshal(reqArg)
+       if err != nil {
+               return nil, errors.Wrap(err, "json marshal")
+       }
+
+       context.Set(reqBodyLabel, string(b))
+
+       return reqArg, nil
+}
+
+func checkDisplayOrder(req interface{}) error {
+       if req == nil {
+               return nil
+       }
+
+       reqType := reflect.TypeOf(req).Elem()
+       reqVal := reflect.ValueOf(req).Elem()
+
+       for i := 0; i < reqType.NumField(); i++ {
+               field := reqType.Field(i)
+               if field.Type != reflect.TypeOf(Display{}) {
+                       continue
+               }
+               display := reqVal.Field(i).Interface().(Display)
+
+               order := strings.Trim(display.Sorter.Order, "")
+               if order != "desc" && order != "asc" {
+                       reqVal.Field(i).Set(reflect.ValueOf(Display{Filter: display.Filter, Sorter: Sorter{By: display.Sorter.By, Order: "desc"}}))
+               }
+       }
+       return nil
+}
+
+func callHandleFunc(fun handlerFun, args ...interface{}) []interface{} {
+       fv := reflect.ValueOf(fun)
+
+       params := make([]reflect.Value, len(args))
+       for i, arg := range args {
+               params[i] = reflect.ValueOf(arg)
+       }
+
+       rs := fv.Call(params)
+       result := make([]interface{}, len(rs))
+       for i, r := range rs {
+               result[i] = r.Interface()
+       }
+       return result
+}
similarity index 99%
rename from toolbar/federation/api/pagination.go
rename to toolbar/server/pagination.go
index f93c1bd..74bf297 100644 (file)
@@ -1,4 +1,4 @@
-package api
+package server
 
 import (
        "fmt"
 
 import (
        "fmt"
similarity index 99%
rename from toolbar/federation/api/response.go
rename to toolbar/server/response.go
index ebb9874..d7ec9d6 100644 (file)
@@ -1,4 +1,4 @@
-package api
+package server
 
 import (
        "fmt"
 
 import (
        "fmt"