package configuration 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 createMiddlewares []gateway.Handler deleteMiddlewares []gateway.Handler queryMiddlewares []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 WithCreateMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.createMiddlewares = middlewares } } func WithDeleteMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.deleteMiddlewares = middlewares } } func WithQueryMiddlewares(middlewares ...gateway.Handler) Option { return func(options *Options) { options.queryMiddlewares = 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) } createMiddlewares := append(options.globalMiddlewares, options.createMiddlewares...) deleteMiddlewares := append(options.globalMiddlewares, options.deleteMiddlewares...) queryMiddlewares := append(options.globalMiddlewares, options.queryMiddlewares...) queryRegisteredServicesMiddlewares := append(options.globalMiddlewares, options.queryRegisteredServicesMiddlewares...) builder := gw.NewBuilder(api.RouterPrefix, "") // 创建 builder. PostRoute("/configuration/create", func(requestBuilder *gateway.RequestBuilder) { jsonBody, err := requestBuilder.Context().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", "/configuration/create") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/create") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } requestBuilder. Post(&gateway.PostRequest{ Url: serviceUrl, }). Request() }, createMiddlewares...) // 删除 builder. PostRoute("/configuration/delete", func(requestBuilder *gateway.RequestBuilder) { jsonBody, err := requestBuilder.Context().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", "/configuration/delete") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/delete") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } requestBuilder. Post(&gateway.PostRequest{ Url: serviceUrl, }). Request() }, deleteMiddlewares...) // 查询 builder. GetRoute("/configuration/values", func(requestBuilder *gateway.RequestBuilder) { queryParams := requestBuilder.Context().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", "/configuration/values") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/values") if err != nil { requestBuilder.ResponseError(err) return } serviceUrl = innerServiceUrl } requestBuilder. Get(&gateway.GetRequest{ Url: serviceUrl, }). Request() }, queryMiddlewares...) // 查询注册的服务 builder. GetRoute("/configuration/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.Context().JSON(http.StatusOK, gin.H{ "services": serviceShortNames, }) }, queryRegisteredServicesMiddlewares...) }