You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

116 lines
2.7 KiB

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))
}