package main import ( "context" "fmt" "github.com/gin-gonic/gin" clientv3 "go.etcd.io/etcd/client/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/resolver" "net/http" config2 "sonet/internal/gateway_http/config" "sonet/pkg/config" "sonet/pkg/grpc/discovery" "sonet/pkg/grpc/generic" "sonet/pkg/utils/logger" "sonet/pkg/utils/resp" "sonet/pkg/utils/shutdown" "sonet/pkg/utils/strs" ) type GatewayHttpConfig struct { Port int IgnoreUrls []string AesTokenKey string } func main() { grpclog.SetLoggerV2(logger.Logger) appConf := &GatewayHttpConfig{} conf := config.LoadConfig(appConf, "cmd/gateway_http") // grpc generic client factory etcdClient, err := clientv3.New(conf.Etcd) if err != nil { panic(err) } etcdResolver := discovery.NewResolver(etcdClient) shutdown.AddShutdownHook(etcdResolver.Close) resolver.Register(etcdResolver) grpcFactory := generic.NewGpcGenericClientFactory(etcdResolver, grpc.WithTransportCredentials(insecure.NewCredentials())) grpcFactory.Init() // gin http server authFilter, err := config2.NewAuthFilter(appConf.AesTokenKey, appConf.IgnoreUrls) if err != nil { panic(err) } server := gin.Default() server.Use(authFilter.Filter) group := server.Group("/api/svc") group.POST("/:svc/:method", func(c *gin.Context) { svc := strs.UpperInitialLetter(c.Param("svc")) method := strs.UpperInitialLetter(c.Param("method")) if svc == "" || method == "" { c.JSON(http.StatusBadRequest, resp.Error("svc not found")) return } ctx := context.Background() grpcClient, err := grpcFactory.GetClient(ctx, svc) if err != nil { c.JSON(http.StatusForbidden, resp.Error(err.Error())) return } body := make(map[string]interface{}) err = c.BindJSON(&body) if err != nil { c.JSON(http.StatusBadRequest, resp.Error("parse request body error: "+err.Error())) return } res, err := grpcClient.InvokeUnaryJson(ctx, method, body) if err != nil { c.JSON(http.StatusInternalServerError, resp.Error(err.Error())) return } // j, err := res.MarshalJSON() // c.Render(http.StatusOK, RenderMarshaledJson{j}) c.JSON(http.StatusOK, resp.Success(res)) }) go func() { err := server.Run(fmt.Sprintf(":%d", appConf.Port)) if err != nil { panic(err) } }() shutdown.Await() } var jsonContentType = []string{"application/json; charset=utf-8"} type RenderMarshaledJson struct { MarshaledJson []byte } func (r RenderMarshaledJson) Render(writer http.ResponseWriter) error { r.WriteContentType(writer) _, err := writer.Write(r.MarshaledJson) return err } func (r RenderMarshaledJson) WriteContentType(w http.ResponseWriter) { header := w.Header() header["Content-Type"] = jsonContentType }