package sig import ( "context" "encoding/json" "io" "net/http" "runtime/debug" "sig-pub/pkg/grpc/generic" "sig-pub/pkg/grpc/session" "sig-pub/pkg/resp" "sig-pub/pkg/utils/strs" "sig-pub/pkg/zlog" "time" "github.com/gin-gonic/gin" "google.golang.org/protobuf/encoding/protojson" ) type SigServer struct { engine *gin.Engine grpcGenericClientFactory *generic.GrpcGenericClientFactory } func NewSigServer(grpcGenericClientFactory *generic.GrpcGenericClientFactory) *SigServer { return &SigServer{ grpcGenericClientFactory: grpcGenericClientFactory, } } func (s *SigServer) Init() (err error) { s.initGinServer() return } func (s *SigServer) initGinServer() { s.engine = gin.Default() s.engine.Use(func(c *gin.Context) { // global recover defer func() { if r := recover(); r != nil { zlog.Error("http server recover error:", r) debug.PrintStack() c.JSON(http.StatusInternalServerError, resp.Error("server error")) c.Abort() } }() c.Next() }) routerGroup := s.engine.Group("/api") routerGroup.POST("/v1/:svr/:method", s.handleGrpcGenericCall) // inst api // tradeInstanceApi := inst.NewTradeInstanceApi() // tradeInstanceApi.InitRoute(routerGroup) } func (s *SigServer) Run(addr string) (err error) { // todo grpc server run return s.engine.Run(addr) } func (s *SigServer) handleGrpcGenericCall(c *gin.Context) { svc := strs.UpperInitialLetter(c.Param("svr")) method := strs.UpperInitialLetter(c.Param("method")) if svc == "" || method == "" { c.JSON(http.StatusBadRequest, resp.Error("service not found")) return } // todo service white list // get request body jsonBody, err := io.ReadAll(c.Request.Body) if err != nil { c.JSON(http.StatusBadRequest, resp.Error("parse request body error: "+err.Error())) return } ctx1, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() grpcGenericClient, err := s.grpcGenericClientFactory.GetClient(ctx1, svc) if err != nil { zlog.Error(err) c.JSON(http.StatusForbidden, resp.Error(err.Error())) return } // put session ctx := context.Background() ctx = session.PutSubject(ctx, session.NewRpcSubject("123456")) ctx, cancel = context.WithTimeout(ctx, time.Second*10) defer cancel() // generic call with json rsp, err := grpcGenericClient.InvokeUnaryJsonBytes(ctx, method, jsonBody) if err != nil { if err == generic.ErrorMethodNotExists { c.JSON(http.StatusNotFound, resp.Error(err.Error())) return } c.JSON(http.StatusInternalServerError, resp.Error(err.Error())) return } // decode response bytes, err := protojson.Marshal(rsp) if err != nil { c.JSON(http.StatusInternalServerError, resp.Error(err.Error())) return } r := json.RawMessage(bytes) c.JSON(http.StatusOK, resp.Success(r)) }