mirror of
https://github.com/gmsec/gmsec.git
synced 2025-09-26 20:01:21 +08:00
165 lines
5.1 KiB
Go
165 lines
5.1 KiB
Go
package routers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"example/internal/api"
|
|
"example/internal/service/hello"
|
|
proto "example/rpc/example"
|
|
|
|
"github.com/chenjiandongx/ginprom"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/gmsec/micro/server"
|
|
"github.com/opentracing/opentracing-go"
|
|
"github.com/opentracing/opentracing-go/ext"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/xxjwxc/ginrpc"
|
|
"github.com/xxjwxc/public/dev"
|
|
"github.com/xxjwxc/public/message"
|
|
"github.com/xxjwxc/public/mylog"
|
|
"github.com/xxjwxc/public/tools"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
// OnInitRoot 初始化
|
|
func OnInitRoot(s server.Server, router gin.IRoutes, objs ...interface{}) {
|
|
var args []interface{}
|
|
h := new(hello.Hello)
|
|
args = append(args, h)
|
|
proto.RegisterExampleServer(s, h) // 服务注册
|
|
args = append(args, objs...)
|
|
OnInitRouter(router, args...)
|
|
}
|
|
|
|
// OnInitRouter 默认初始化
|
|
func OnInitRouter(router gin.IRoutes, objs ...interface{}) {
|
|
InitFunc(router)
|
|
InitObj(router, objs...)
|
|
init3rdGrpcHost()
|
|
}
|
|
|
|
// 初始化第三方host
|
|
func init3rdGrpcHost() {
|
|
// micro.SetClientServiceName(oauth2.GetOauth2Name(), "gmsec.srv.oauth2")
|
|
}
|
|
|
|
// InitFunc 默认初始化函数
|
|
func InitFunc(router gin.IRoutes) {
|
|
router.StaticFS("/file", http.Dir(tools.GetCurrentDirectory()+"/file")) //加载静态资源,一般是上传的资源,例如用户上传的图片
|
|
router.GET("/health", func(c *gin.Context) {
|
|
c.String(http.StatusOK, "ok")
|
|
}) // 健康检查
|
|
router.GET("/metrics", ginprom.PromHandler(promhttp.Handler())) // 添加grafana监控
|
|
}
|
|
|
|
// InitObj 初始化对象
|
|
func InitObj(router gin.IRoutes, objs ...interface{}) {
|
|
base := ginrpc.New(ginrpc.WithCtx(api.NewAPIFunc), ginrpc.WithOutDoc(dev.IsDev()), ginrpc.WithDebug(dev.IsDev()),
|
|
ginrpc.WithOutPath("internal/routers"), ginrpc.WithImportFile("rpc/common", "../apidoc/rpc/common"),
|
|
ginrpc.WithBeforeAfter(&JagerGinBeforeAfter{}))
|
|
|
|
base.OutDoc(true)
|
|
base.Register(router, objs...) // 对象注册
|
|
}
|
|
|
|
// Cors 跨域问题
|
|
func Cors() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
method := c.Request.Method
|
|
|
|
origin := c.Request.Header.Get("Origin")
|
|
var headerKeys []string
|
|
for k := range c.Request.Header {
|
|
headerKeys = append(headerKeys, k)
|
|
}
|
|
headerStr := strings.Join(headerKeys, ", ")
|
|
if headerStr != "" {
|
|
headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
|
|
} else {
|
|
headerStr = "access-control-allow-origin, access-control-allow-headers"
|
|
}
|
|
if origin != "" {
|
|
//下面的都是乱添加的-_-~
|
|
// c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
|
c.Header("Access-Control-Allow-Origin", "*")
|
|
c.Header("Access-Control-Allow-Headers", headerStr)
|
|
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
// c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
|
|
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
|
|
// c.Header("Access-Control-Max-Age", "172800")
|
|
c.Header("Access-Control-Allow-Credentials", "true")
|
|
c.Set("content-type", "application/json")
|
|
}
|
|
|
|
//放行所有OPTIONS方法
|
|
if method == "OPTIONS" {
|
|
c.JSON(http.StatusOK, "Options Request!")
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|
|
|
|
// UseJager 链路追踪
|
|
func UseJager(_tracer opentracing.Tracer) gin.HandlerFunc {
|
|
return func(ctx *gin.Context) {
|
|
path := ctx.Request.URL.Path
|
|
span := _tracer.StartSpan(path, ext.SpanKindRPCServer)
|
|
ext.HTTPUrl.Set(span, path)
|
|
ext.HTTPMethod.Set(span, ctx.Request.Method)
|
|
c := opentracing.ContextWithSpan(ctx, span)
|
|
ctx.Set("jager_ctx", c)
|
|
ctx.Next()
|
|
req, _ := ctx.Get("jager_req")
|
|
span.SetTag("request", req)
|
|
resp, _ := ctx.Get("jager_resp")
|
|
span.SetTag("response", resp)
|
|
ext.HTTPStatusCode.Set(span, uint16(ctx.Writer.Status()))
|
|
span.Finish()
|
|
// tracer.CloseTracer()
|
|
}
|
|
}
|
|
|
|
// JagerGinBeforeAfter 创建一个默认 BeforeAfter Middleware
|
|
type JagerGinBeforeAfter struct {
|
|
}
|
|
|
|
type timeTrace struct{}
|
|
|
|
// GinBefore call之前调用
|
|
func (d *JagerGinBeforeAfter) GinBefore(req *ginrpc.GinBeforeAfterInfo) bool {
|
|
req.Context = context.WithValue(req.Context, timeTrace{}, time.Now())
|
|
req.C.Set("jager_req", tools.JSONDecode(req.Req))
|
|
return true
|
|
}
|
|
|
|
// GinAfter call之后调用
|
|
func (d *JagerGinBeforeAfter) GinAfter(req *ginrpc.GinBeforeAfterInfo) bool {
|
|
begin := (req.Context.Value(timeTrace{})).(time.Time)
|
|
now := time.Now()
|
|
mylog.Info(fmt.Sprintf("[middleware] call[%v] [%v]", req.FuncName, now.Sub(begin)))
|
|
|
|
msg := message.GetSuccessMsg()
|
|
if req.Error != nil {
|
|
msg = message.GetErrorMsg(message.InValidOp)
|
|
gerr := status.Convert(req.Error)
|
|
if gerr != nil {
|
|
msg.Code = int(gerr.Code())
|
|
msg.Error = gerr.Message()
|
|
} else {
|
|
msg.Error = req.Error.Error()
|
|
}
|
|
} else {
|
|
msg.Data = req.Resp
|
|
}
|
|
|
|
req.Resp = msg // 设置resp 结果
|
|
req.C.Set("jager_resp", tools.JSONDecode(msg))
|
|
|
|
return true
|
|
}
|