Files
gmsec/example/internal/routers/api_root.go
2022-08-18 19:28:33 +08:00

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
}