diff --git a/cmd/internal/svc/codegen/grpcproto_test.go b/cmd/internal/svc/codegen/grpcproto_test.go new file mode 100644 index 00000000..23d4e179 --- /dev/null +++ b/cmd/internal/svc/codegen/grpcproto_test.go @@ -0,0 +1,19 @@ +package codegen + +import ( + "fmt" + "github.com/iancoleman/strcase" + v3 "github.com/unionj-cloud/go-doudou/v2/cmd/internal/protobuf/v3" + "github.com/unionj-cloud/go-doudou/v2/toolkit/astutils" + "path/filepath" + "testing" +) + +func TestGenGrpcProto(t *testing.T) { + svcfile := filepath.Join(testDir, "svc.go") + ic := astutils.BuildInterfaceCollector(svcfile, astutils.ExprString) + p := v3.NewProtoGenerator(v3.WithFieldNamingFunc(strcase.ToLowerCamel)) + ParseDtoGrpc(testDir, p, "dto") + _, gotProtoFile := GenGrpcProto(testDir, ic, p) + fmt.Println(gotProtoFile) +} diff --git a/cmd/internal/svc/codegen/testdata/dto/dto.go b/cmd/internal/svc/codegen/testdata/dto/dto.go index 55ac8b34..1a595b07 100644 --- a/cmd/internal/svc/codegen/testdata/dto/dto.go +++ b/cmd/internal/svc/codegen/testdata/dto/dto.go @@ -1,7 +1,41 @@ +/** +* Generated by go-doudou v2.0.4. +* You can edit it as your need. + */ package dto import "github.com/shopspring/decimal" +type StringSliceWrapper struct { + Value []string +} + +// DroppedTarget DroppedTarget has the information for one target that was dropped during relabelling. +type DroppedTarget struct { + DiscoveredLabels map[string]StringSliceWrapper `json:"discoveredLabels"` +} + +// Target Target has the information for one target. +type Target struct { + DiscoveredLabels map[string]StringSliceWrapper `json:"discoveredLabels"` + + GlobalURL *string `json:"globalURL"` + + Health *TargetHealth `json:"health"` + + Labels *Labels `json:"labels"` + + LastError *string `json:"lastError"` + + LastScrape *string `json:"lastScrape"` + + LastScrapeDuration *float64 `json:"lastScrapeDuration"` + + ScrapePool *string `json:"scrapePool"` + + ScrapeURL *string `json:"scrapeURL"` +} + type Laptop struct { Price decimal.Decimal } diff --git a/cmd/internal/svc/codegen/testdata/transport/grpc/usersvc.proto b/cmd/internal/svc/codegen/testdata/transport/grpc/usersvc.proto new file mode 100644 index 00000000..cb014151 --- /dev/null +++ b/cmd/internal/svc/codegen/testdata/transport/grpc/usersvc.proto @@ -0,0 +1,104 @@ +/** +* Generated by go-doudou v2.0.4. +* Don't edit! +* +* Version No.: v20230115 +*/ +syntax = "proto3"; + +package usersvc; +option go_package = "testdata/transport/grpc"; + +import "google/protobuf/any.proto"; + + +message DownloadAvatarRpcRequest { + google.protobuf.Any userId = 1 [json_name="userId"]; + bytes data = 2 [json_name="data"]; + repeated string userAttrs = 3 [json_name="userAttrs"]; +} + +message DownloadAvatarRpcResponse { + bytes rf = 1 [json_name="rf"]; +} + +// DroppedTarget DroppedTarget has the information for one target that was dropped during relabelling. +message DroppedTarget { + map discoveredLabels = 1 [json_name="discoveredLabels"]; +} + +message GetUserRpcRequest { + // 用户ID + string userId = 1 [json_name="userId"]; + // 图片地址 + string photo = 2 [json_name="photo"]; +} + +message GetUserRpcResponse { + int32 code = 1 [json_name="code"]; + string data = 2 [json_name="data"]; +} + +message PageUsersRpcResponse { + int32 code = 1 [json_name="code"]; + google.protobuf.Any data = 2 [json_name="data"]; +} + +message SignUpRpcRequest { + string username = 1 [json_name="username"]; + int32 password = 2 [json_name="password"]; + bool actived = 3 [json_name="actived"]; + repeated int32 score = 4 [json_name="score"]; +} + +message SignUpRpcResponse { + int32 code = 1 [json_name="code"]; + string data = 2 [json_name="data"]; +} + +message StringSliceWrapper { + repeated string value = 1 [json_name="value"]; +} + +// Target Target has the information for one target. +message Target { + map discoveredLabels = 1 [json_name="discoveredLabels"]; + string globalURL = 2 [json_name="globalURL"]; + google.protobuf.Any health = 3 [json_name="health"]; + google.protobuf.Any labels = 4 [json_name="labels"]; + string lastError = 5 [json_name="lastError"]; + string lastScrape = 6 [json_name="lastScrape"]; + double lastScrapeDuration = 7 [json_name="lastScrapeDuration"]; + string scrapePool = 8 [json_name="scrapePool"]; + string scrapeURL = 9 [json_name="scrapeURL"]; +} + +message UploadAvatarRpcRequest { + repeated bytes pf = 1 [json_name="pf"]; + string ps = 2 [json_name="ps"]; + bytes pf2 = 3 [json_name="pf2"]; + google.protobuf.Any pf3 = 4 [json_name="pf3"]; + repeated google.protobuf.Any pf4 = 5 [json_name="pf4"]; +} + +message UploadAvatarRpcResponse { + int32 ri = 1 [json_name="ri"]; + google.protobuf.Any ri2 = 2 [json_name="ri2"]; +} + +service UsersvcService { + // You can define your service methods as your need. Below is an example.@role(user) + rpc PageUsersRpc(google.protobuf.Any) returns (PageUsersRpcResponse); + // comment1 +// comment2 +// @role(admin) + rpc GetUserRpc(GetUserRpcRequest) returns (GetUserRpcResponse); + // comment3 +// @permission(create,update)@role(admin) + rpc SignUpRpc(SignUpRpcRequest) returns (SignUpRpcResponse); + // comment4 +// @role(user) + rpc UploadAvatarRpc(UploadAvatarRpcRequest) returns (UploadAvatarRpcResponse); + // comment5 + rpc DownloadAvatarRpc(DownloadAvatarRpcRequest) returns (DownloadAvatarRpcResponse); +} diff --git a/framework/rest/server.go b/framework/rest/server.go index 1250cf0b..3446f25f 100644 --- a/framework/rest/server.go +++ b/framework/rest/server.go @@ -86,13 +86,14 @@ func toMiddlewareFunc(m func(http.Handler) http.HandlerFunc) MiddlewareFunc { // RestServer wraps httpRouter router type RestServer struct { - bizRouter *httprouter.RouteGroup - rootRouter *httprouter.Router - gddRoutes []Route - debugRoutes []Route - bizRoutes []Route - middlewares []MiddlewareFunc - data map[string]interface{} + bizRouter *httprouter.RouteGroup + rootRouter *httprouter.Router + gddRoutes []Route + debugRoutes []Route + bizRoutes []Route + middlewares []MiddlewareFunc + data map[string]interface{} + panicHandler func(inner http.Handler) http.Handler } func (srv *RestServer) printRoutes() { @@ -143,8 +144,9 @@ func NewRestServer(data ...map[string]interface{}) *RestServer { rootRouter := httprouter.New() rootRouter.SaveMatchedRoutePath = cast.ToBoolOrDefault(config.GddRouterSaveMatchedRoutePath.Load(), config.DefaultGddRouterSaveMatchedRoutePath) srv := &RestServer{ - bizRouter: rootRouter.NewGroup(rr), - rootRouter: rootRouter, + bizRouter: rootRouter.NewGroup(rr), + rootRouter: rootRouter, + panicHandler: recovery, } srv.middlewares = append(srv.middlewares, tracing, @@ -171,6 +173,61 @@ func NewRestServer(data ...map[string]interface{}) *RestServer { return srv } +type ServerOption func(server *RestServer) + +func WithPanicHandler(panicHandler func(inner http.Handler) http.Handler) ServerOption { + return func(server *RestServer) { + server.panicHandler = panicHandler + } +} + +func WithUserData(userData map[string]interface{}) ServerOption { + return func(server *RestServer) { + server.data = userData + } +} + +// NewRestServerWithOptions create a RestServer instance with options +func NewRestServerWithOptions(options ...ServerOption) *RestServer { + rr := config.DefaultGddRouteRootPath + if stringutils.IsNotEmpty(config.GddRouteRootPath.Load()) { + rr = config.GddRouteRootPath.Load() + } + if stringutils.IsEmpty(rr) { + rr = "/" + } + rootRouter := httprouter.New() + rootRouter.SaveMatchedRoutePath = cast.ToBoolOrDefault(config.GddRouterSaveMatchedRoutePath.Load(), config.DefaultGddRouterSaveMatchedRoutePath) + srv := &RestServer{ + bizRouter: rootRouter.NewGroup(rr), + rootRouter: rootRouter, + panicHandler: recovery, + } + for _, fn := range options { + fn(srv) + } + srv.middlewares = append(srv.middlewares, + tracing, + metrics, + ) + if cast.ToBoolOrDefault(config.GddEnableResponseGzip.Load(), config.DefaultGddEnableResponseGzip) { + gzipMiddleware, err := gzhttp.NewWrapper(gzhttp.ContentTypes(contentTypeShouldbeGzip)) + if err != nil { + panic(err) + } + srv.middlewares = append(srv.middlewares, toMiddlewareFunc(gzipMiddleware)) + } + if cast.ToBoolOrDefault(config.GddLogReqEnable.Load(), config.DefaultGddLogReqEnable) { + srv.middlewares = append(srv.middlewares, log) + } + srv.middlewares = append(srv.middlewares, + requestid.RequestIDHandler, + handlers.ProxyHeaders, + fallbackContentType(config.GddFallbackContentType.LoadOrDefault(config.DefaultGddFallbackContentType)), + ) + return srv +} + // AddRoute adds routes to router func (srv *RestServer) AddRoute(route ...Route) { srv.bizRoutes = append(srv.bizRoutes, route...) @@ -374,7 +431,7 @@ func (srv *RestServer) Run() { debugRouter.Handler(item.Method, "/"+strings.TrimPrefix(item.Pattern, debugPathPrefix), h, item.Name) } } - srv.middlewares = append(srv.middlewares, recovery) + srv.middlewares = append(srv.middlewares, srv.panicHandler) for _, item := range srv.bizRoutes { h := http.Handler(item.HandlerFunc) for i := len(srv.middlewares) - 1; i >= 0; i-- {