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