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.
 
 

113 lines
2.7 KiB

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
}