package sql_executor import ( "git.sxidc.com/go-framework/baize/framework/core/api" "git.sxidc.com/go-framework/baize/framework/gateway" "git.sxidc.com/go-tools/utils/strutils" "github.com/gin-gonic/gin" "github.com/pkg/errors" "net/http" "net/url" "sync" ) type Option func(options *Options) type Options struct { serviceApiVersion string globalMiddlewares []gateway.Handler executeSqlMiddlewares []gateway.Handler sqlExecuteLogMiddlewares []gateway.Handler queryRegisteredServicesMiddlewares []gateway.Handler } func WithServiceApiVersion(serviceApiVersion string) Option { return func(options *Options) { options.serviceApiVersion = serviceApiVersion } } func WithGlobalMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.globalMiddlewares = middlewares } } func WithExecuteSqlMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.executeSqlMiddlewares = middlewares } } func WithSqlExecuteLogMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.sqlExecuteLogMiddlewares = middlewares } } func WithQueryRegisteredServicesMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.queryRegisteredServicesMiddlewares = middlewares } } var serviceBaseUrlMap sync.Map func RegisterService(serviceShortName string, baseUrl string) { serviceBaseUrlMap.Store(serviceShortName, baseUrl) } func BuildGateway(gw *gateway.Gateway, opts ...Option) { options := new(Options) for _, opt := range opts { opt(options) } executeSqlMiddlewares := append(options.globalMiddlewares, options.executeSqlMiddlewares...) sqlExecuteLogMiddlewares := append(options.globalMiddlewares, options.sqlExecuteLogMiddlewares...) queryRegisteredServicesMiddlewares := append(options.globalMiddlewares, options.queryRegisteredServicesMiddlewares...) builder := gw.NewBuilder(api.RouterPrefix, "") builder. PostRouteWithUserIDCommon("/sql/execute", "executorId", func(requestBuilder *gateway.RequestBuilder) { jsonBody, err := requestBuilder.ApiContext().GetJsonBody() if err != nil { requestBuilder.ResponseError(err) return } serviceShortName, ok := jsonBody.Get("serviceShortName").(string) if !ok { requestBuilder.ResponseError(errors.New("没有传递服务名缩写或服务名缩写不是string类型")) return } jsonBody.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { requestBuilder.ResponseError(errors.New("没有注册对应的服务: " + serviceShortName)) return } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/sql/execute") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/sql/execute") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } userInfo := requestBuilder.ApiContext().GetUserInfo() if userInfo == nil { jsonBody.Set("executorName", "guest") } else { jsonBody.Set("executorName", userInfo.GetName) } requestBuilder. Post(&gateway.PostRequest{ Url: serviceUrl, }). Request() }, executeSqlMiddlewares...) builder. GetRouteWithUserIDCommon("/sql/execute/log", "executorId", func(requestBuilder *gateway.RequestBuilder) { queryParams := requestBuilder.ApiContext().GetQueryParams() serviceShortName := queryParams.Get("serviceShortName") if strutils.IsStringEmpty(serviceShortName) { requestBuilder.ResponseError(errors.New("没有传递服务名缩写")) return } queryParams.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { requestBuilder.ResponseError(errors.New("没有注册对应的服务: " + serviceShortName)) return } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/sql/execute/log") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/sql/execute/log") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } requestBuilder. Get(&gateway.GetRequest{ Url: serviceUrl, }). Request() }, sqlExecuteLogMiddlewares...) // 查询注册的服务 builder. GetRoute("/sql/execute/registered/services", func(requestBuilder *gateway.RequestBuilder) { serviceShortNames := make([]string, 0) serviceBaseUrlMap.Range(func(key any, value any) bool { serviceShortNames = append(serviceShortNames, key.(string)) return true }) requestBuilder.ApiContext().JSON(http.StatusOK, gin.H{ "services": serviceShortNames, }) }, queryRegisteredServicesMiddlewares...) }