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 []api.Handler createMiddlewares []api.Handler deleteMiddlewares []api.Handler queryMiddlewares []api.Handler queryRegisteredServicesMiddlewares []api.Handler } func WithServiceApiVersion(serviceApiVersion string) Option { return func(options *Options) { options.serviceApiVersion = serviceApiVersion } } func WithGlobalMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.globalMiddlewares = middlewares } } func WithCreateMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.createMiddlewares = middlewares } } func WithDeleteMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.deleteMiddlewares = middlewares } } func WithQueryMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.queryMiddlewares = middlewares } } func WithQueryRegisteredServicesMiddlewares(middlewares ...api.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. Url(http.MethodPost, "/configuration/create"). Post(&gateway.PostRequest{ UrlFormFunc: func(c *api.Context, _ string, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (string, error) { jsonBody, err := c.GetJsonBody() if err != nil { return "", err } serviceShortName, ok := jsonBody.Get("serviceShortName").(string) if !ok { return "", errors.New("没有传递服务名缩写或服务名缩写不是string类型") } jsonBody.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { return "", errors.New("没有注册对应的服务: " + serviceShortName) } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/configuration/create") if err != nil { return "", err } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/create") if err != nil { return "", err } serviceUrl = innerServiceUrl } return serviceUrl, nil }, }). Build(createMiddlewares...) // 删除 builder. Url(http.MethodPost, "/configuration/delete"). Post(&gateway.PostRequest{ UrlFormFunc: func(c *api.Context, _ string, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (string, error) { jsonBody, err := c.GetJsonBody() if err != nil { return "", err } serviceShortName, ok := jsonBody.Get("serviceShortName").(string) if !ok { return "", errors.New("没有传递服务名缩写或服务名缩写不是string类型") } jsonBody.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { return "", errors.New("没有注册对应的服务: " + serviceShortName) } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/configuration/delete") if err != nil { return "", err } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/delete") if err != nil { return "", err } serviceUrl = innerServiceUrl } return serviceUrl, nil }, }). Build(deleteMiddlewares...) // 查询 builder. Url(http.MethodGet, "/configuration/values"). Get(&gateway.GetRequest{ UrlFormFunc: func(c *api.Context, _ string, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (string, error) { queryParams := c.GetQueryParams() serviceShortName := queryParams.Get("serviceShortName") if strutils.IsStringEmpty(serviceShortName) { return "", errors.New("没有传递服务名缩写") } queryParams.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { return "", errors.New("没有注册对应的服务: " + serviceShortName) } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/configuration/values") if err != nil { return "", err } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/configuration/values") if err != nil { return "", err } serviceUrl = innerServiceUrl } return serviceUrl, nil }, }). Build(queryMiddlewares...) // 查询注册的服务 builder. Url(http.MethodGet, "/configuration/registered/services"). Local(func(c *api.Context) { serviceShortNames := make([]string, 0) serviceBaseUrlMap.Range(func(key any, value any) bool { serviceShortNames = append(serviceShortNames, key.(string)) return true }) c.JSON(http.StatusOK, gin.H{ "services": serviceShortNames, }) }, queryRegisteredServicesMiddlewares...) }