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.
 
 

111 lines
2.5 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"
"net/http"
"runtime/debug"
config2 "sonet/internal/gateway_http/config"
"sonet/internal/gateway_http/logic"
"sonet/pkg/config"
"sonet/pkg/grpc/discovery"
"sonet/pkg/grpc/generic"
"sonet/pkg/utils/logger"
"sonet/pkg/utils/resp"
"sonet/pkg/utils/shutdown"
)
type GatewayHttpConfig struct {
Port int
IgnoreUrls []string
AesTokenKey string
}
func main() {
appConf := &GatewayHttpConfig{}
conf := config.LoadConfig(appConf, "cmd/gateway_http")
// grpc generic client factory
etcdClient, err := clientv3.New(conf.Etcd)
if err != nil {
panic(err)
}
shutdown.AddHook(func() {
if err := etcdClient.Close(); err != nil {
panic(err)
}
}, shutdown.WithOrderBack())
// gin http server
authFilter, err := config2.NewAuthFilter(appConf.AesTokenKey, appConf.IgnoreUrls)
if err != nil {
panic(err)
}
server := gin.Default()
server.Use(func(c *gin.Context) {
// global recover
defer func() {
if r := recover(); r != nil {
logger.Error("http server recover error:", r)
debug.PrintStack()
c.JSON(http.StatusInternalServerError, resp.Error("server error"))
c.Abort()
}
}()
c.Next()
})
server.Use(authFilter.Filter)
// grpc services
grpcGroup := server.Group("/api/svc")
dis := discovery.NewEtcdDiscovery(etcdClient)
resolver, err := dis.Resolver()
if err != nil {
panic(err)
}
grpcFactory := generic.NewGpcGenericClientFactory(
discovery.EtcdSchema,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithResolvers(resolver),
)
grpcFactory.Init()
grpcGenericHandler := logic.NewGrpcGenericHandler(grpcFactory)
grpcGenericHandler.Route(grpcGroup)
// postal loadBalancer handler
postalBalancer := logic.NewPostalBalancer()
postalBalancer.Init(context.Background(), resolver)
server.GET("/api/lb/ws", postalBalancer.Endpoint)
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
}