This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch refactor-with-go
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git


The following commit(s) were added to refs/heads/refactor-with-go by this push:
     new 5b14d8f  ADD: SearchService (#1005)
5b14d8f is described below

commit 5b14d8f0b830d07f7136bf5544a8b2b4395781ea
Author: wudong5 <[email protected]>
AuthorDate: Fri Mar 3 11:14:12 2023 +0800

    ADD: SearchService (#1005)
---
 dubbo-admin-server/admin.go                        |  7 +-
 dubbo-admin-server/pkg/constant/const.go           |  9 +++
 dubbo-admin-server/pkg/handlers/service.go         | 29 +++----
 dubbo-admin-server/pkg/model/entity.go             |  6 ++
 dubbo-admin-server/pkg/model/provider.go           | 22 +++++
 dubbo-admin-server/pkg/model/registry_source.go    | 11 +++
 .../pkg/services/provider_service.go               |  8 ++
 .../pkg/services/provider_service_impl.go          | 67 +++++++++++++++
 .../pkg/services/registry_service_sync.go          | 94 +++++++++++-----------
 dubbo-admin-server/pkg/util/sync_utils.go          | 29 +++++++
 dubbo-admin-server/router/router.go                |  1 +
 11 files changed, 222 insertions(+), 61 deletions(-)

diff --git a/dubbo-admin-server/admin.go b/dubbo-admin-server/admin.go
index 493f9cb..5cf3fcd 100644
--- a/dubbo-admin-server/admin.go
+++ b/dubbo-admin-server/admin.go
@@ -25,7 +25,10 @@ import (
 
 func main() {
        config.LoadConfig()
-       services.StartSubscribe(config.RegistryCenter)
+       go services.StartSubscribe(config.RegistryCenter)
+       defer func() {
+               services.DestroySubscribe(config.RegistryCenter)
+       }()
        router := router.InitRouter()
-       router.Run(":38080")
+       _ = router.Run(":38080")
 }
diff --git a/dubbo-admin-server/pkg/constant/const.go 
b/dubbo-admin-server/pkg/constant/const.go
index 4a90131..23f2658 100644
--- a/dubbo-admin-server/pkg/constant/const.go
+++ b/dubbo-admin-server/pkg/constant/const.go
@@ -42,4 +42,13 @@ const (
        ProviderSide          = "provider"
        ConsumerProtocol      = "consumer"
        EmptyProtocol         = "empty"
+       ApplicationKey        = "application"
+       DynamicKey            = "dynamic"
+       SerializationKey      = "serialization"
+       TimeoutKey            = "timeout"
+       DefaultTimeout        = 1000
+       WeightKey             = "weight"
+       DefaultWeight         = 100
+       OwnerKey              = "owner"
+       Service               = "service"
 )
diff --git a/dubbo-admin-server/pkg/handlers/service.go 
b/dubbo-admin-server/pkg/handlers/service.go
index e097cb2..8a036aa 100644
--- a/dubbo-admin-server/pkg/handlers/service.go
+++ b/dubbo-admin-server/pkg/handlers/service.go
@@ -18,26 +18,27 @@
 package handlers
 
 import (
-       "admin/pkg/cache"
-       "admin/pkg/constant"
+       "admin/pkg/services"
        "github.com/gin-gonic/gin"
        "net/http"
-       "sync"
 )
 
+var providerService services.ProviderService = &services.ProviderServiceImpl{}
+
 func AllServices(c *gin.Context) {
-       services, ok := 
cache.InterfaceRegistryCache.Load(constant.ProvidersCategory)
-       var value []string
-       if !ok {
-               value = []string{}
-       } else {
-               services.(*sync.Map).Range(func(key, v interface{}) bool {
-                       value = append(value, key.(string))
-                       return true
-               })
-       }
+       services := providerService.FindServices()
+       c.JSON(http.StatusOK, gin.H{
+               "code": 1,
+               "data": services,
+       })
+}
+
+func SearchService(c *gin.Context) {
+       pattern := c.Query("pattern")
+       filter := c.Query("filter")
+       providers := providerService.FindService(pattern, filter)
        c.JSON(http.StatusOK, gin.H{
                "code": 1,
-               "data": value,
+               "data": providers,
        })
 }
diff --git a/dubbo-admin-server/pkg/model/entity.go 
b/dubbo-admin-server/pkg/model/entity.go
new file mode 100644
index 0000000..40fc3cd
--- /dev/null
+++ b/dubbo-admin-server/pkg/model/entity.go
@@ -0,0 +1,6 @@
+package model
+
+type Entity struct {
+       ID   string
+       Hash string
+}
diff --git a/dubbo-admin-server/pkg/model/provider.go 
b/dubbo-admin-server/pkg/model/provider.go
new file mode 100644
index 0000000..e0c4a29
--- /dev/null
+++ b/dubbo-admin-server/pkg/model/provider.go
@@ -0,0 +1,22 @@
+package model
+
+import "time"
+
+type Provider struct {
+       Entity
+       Service        string
+       URL            string
+       Parameters     string
+       Address        string
+       Registry       string
+       Dynamic        bool
+       Enabled        bool
+       Timeout        int64
+       Serialization  string
+       Weight         int64
+       Application    string
+       Username       string
+       Expired        time.Duration
+       Alived         int64
+       RegistrySource RegistrySource
+}
diff --git a/dubbo-admin-server/pkg/model/registry_source.go 
b/dubbo-admin-server/pkg/model/registry_source.go
new file mode 100644
index 0000000..32057de
--- /dev/null
+++ b/dubbo-admin-server/pkg/model/registry_source.go
@@ -0,0 +1,11 @@
+package model
+
+type RegistrySource int
+
+const (
+       All RegistrySource = iota
+
+       Interface
+
+       Instance
+)
diff --git a/dubbo-admin-server/pkg/services/provider_service.go 
b/dubbo-admin-server/pkg/services/provider_service.go
new file mode 100644
index 0000000..0eef9fe
--- /dev/null
+++ b/dubbo-admin-server/pkg/services/provider_service.go
@@ -0,0 +1,8 @@
+package services
+
+import "admin/pkg/model"
+
+type ProviderService interface {
+       FindServices() []string
+       FindService(string, string) []*model.Provider
+}
diff --git a/dubbo-admin-server/pkg/services/provider_service_impl.go 
b/dubbo-admin-server/pkg/services/provider_service_impl.go
new file mode 100644
index 0000000..85ceebe
--- /dev/null
+++ b/dubbo-admin-server/pkg/services/provider_service_impl.go
@@ -0,0 +1,67 @@
+package services
+
+import (
+       "admin/pkg/cache"
+       "admin/pkg/constant"
+       "admin/pkg/model"
+       "admin/pkg/util"
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
+       "sync"
+)
+
+type ProviderServiceImpl struct{}
+
+func (p *ProviderServiceImpl) FindServices() []string {
+       servicesMap, ok := 
cache.InterfaceRegistryCache.Load(constant.ProvidersCategory)
+       var services []string
+       if !ok {
+               return services
+       }
+       servicesMap.(*sync.Map).Range(func(key, v interface{}) bool {
+               services = append(services, key.(string))
+               return true
+       })
+       return services
+}
+
+func (p *ProviderServiceImpl) findByService(serviceName string) 
[]*model.Provider {
+       var providers []*model.Provider
+       addProvider := func(serviceMap any) {
+               for id, url := range serviceMap.(map[string]*common.URL) {
+                       provider := util.URL2Provider(id, url)
+                       if provider != nil {
+                               providers = append(providers, provider)
+                       }
+               }
+       }
+       services, ok := 
cache.InterfaceRegistryCache.Load(constant.ProvidersCategory)
+       if !ok {
+               return providers
+       }
+       servicesMap, ok := services.(*sync.Map)
+       if !ok {
+               // servicesMap type error
+               logger.Error("servicesMap type not *sync.Map")
+               return providers
+       }
+       if serviceName == constant.AnyValue {
+               servicesMap.Range(func(key, value any) bool {
+                       addProvider(value)
+                       return true
+               })
+       }
+       serviceMap, ok := servicesMap.Load(serviceName)
+       if !ok {
+               return providers
+       }
+       addProvider(serviceMap)
+       return providers
+}
+
+func (p *ProviderServiceImpl) FindService(pattern string, filter string) 
[]*model.Provider {
+       if pattern == constant.Service {
+               return p.findByService(filter)
+       }
+       return nil
+}
diff --git a/dubbo-admin-server/pkg/services/registry_service_sync.go 
b/dubbo-admin-server/pkg/services/registry_service_sync.go
index 3390e8f..c9bd1ee 100644
--- a/dubbo-admin-server/pkg/services/registry_service_sync.go
+++ b/dubbo-admin-server/pkg/services/registry_service_sync.go
@@ -21,11 +21,13 @@ import (
        "admin/pkg/cache"
        "admin/pkg/constant"
        util2 "admin/pkg/util"
-       "dubbo.apache.org/dubbo-go/v3/common"
-       "dubbo.apache.org/dubbo-go/v3/registry"
+       "dubbo.apache.org/dubbo-go/v3/common/logger"
        "net/url"
        "strings"
        "sync"
+
+       "dubbo.apache.org/dubbo-go/v3/common"
+       "dubbo.apache.org/dubbo-go/v3/registry"
 )
 
 var SUBSCRIBE *common.URL
@@ -54,36 +56,46 @@ func StartSubscribe(registry registry.Registry) {
        registry.Subscribe(SUBSCRIBE, adminNotifyListener{})
 }
 
+func DestroySubscribe(registry registry.Registry) {
+       registry.Destroy()
+}
+
 type adminNotifyListener struct{}
 
 func (adminNotifyListener) Notify(event *registry.ServiceEvent) {
        //TODO implement me
-       serviceUrl := event.Service
+       serviceURL := event.Service
        var interfaceName string
        categories := make(map[string]map[string]map[string]*common.URL)
-       category := serviceUrl.GetParam(constant.CategoryKey, "")
+       category := serviceURL.GetParam(constant.CategoryKey, "")
        if len(category) == 0 {
-               if constant.ConsumerSide == serviceUrl.GetParam(constant.Side, 
"") ||
-                       constant.ConsumerProtocol == serviceUrl.Protocol {
+               if constant.ConsumerSide == serviceURL.GetParam(constant.Side, 
"") ||
+                       constant.ConsumerProtocol == serviceURL.Protocol {
                        category = constant.ConsumersCategory
                } else {
                        category = constant.ProvidersCategory
                }
        }
-       if strings.EqualFold(constant.EmptyProtocol, serviceUrl.Protocol) {
+       if strings.EqualFold(constant.EmptyProtocol, serviceURL.Protocol) {
                if services, ok := cache.InterfaceRegistryCache.Load(category); 
ok {
                        if services != nil {
-                               group := serviceUrl.GetParam(constant.GroupKey, 
"")
-                               version := 
serviceUrl.GetParam(constant.VersionKey, "")
-                               if constant.AnyValue == group && 
constant.AnyValue != version {
-                                       
services.(*sync.Map).Delete(getServiceInterface(serviceUrl))
+                               servicesMap, ok := services.(*sync.Map)
+                               if !ok {
+                                       // servicesMap type error
+                                       logger.Error("servicesMap type not 
*sync.Map")
+                                       return
+                               }
+                               group := serviceURL.Group()
+                               version := serviceURL.Version()
+                               if constant.AnyValue != group && 
constant.AnyValue != version {
+                                       servicesMap.Delete(serviceURL.Service())
                                } else {
                                        // iterator services
-                                       services.(*sync.Map).Range(func(key, 
value interface{}) bool {
-                                               if 
util2.GetInterface(key.(string)) == getServiceInterface(serviceUrl) &&
+                                       servicesMap.Range(func(key, value 
interface{}) bool {
+                                               if 
util2.GetInterface(key.(string)) == serviceURL.Service() &&
                                                        (constant.AnyValue == 
group || group == util2.GetGroup(key.(string))) &&
                                                        (constant.AnyValue == 
version || version == util2.GetVersion(key.(string))) {
-                                                       
services.(*sync.Map).Delete(key)
+                                                       servicesMap.Delete(key)
                                                }
                                                return true
                                        })
@@ -91,28 +103,26 @@ func (adminNotifyListener) Notify(event 
*registry.ServiceEvent) {
                        }
                }
        } else {
-               interfaceName = getServiceInterface(serviceUrl)
+               interfaceName = serviceURL.Service()
                var services map[string]map[string]*common.URL
                if _, ok := categories[category]; ok {
                        //services = s
                } else {
                        services = make(map[string]map[string]*common.URL)
                        categories[category] = services
-                       group := serviceUrl.GetParam(constant.GroupKey, "")
-                       version := serviceUrl.GetParam(constant.VersionKey, "")
-                       service := 
util2.BuildServiceKey(getServiceInterface(serviceUrl), group, version)
-                       ids, found := services[service]
-                       if !found {
-                               ids = make(map[string]*common.URL)
-                               services[service] = ids
-                       }
-                       if md5, ok := UrlIdsMapper.Load(serviceUrl.Key()); ok {
-                               ids[md5.(string)] = serviceUrl
-                       } else {
-                               md5 := util2.Md5_16bit(serviceUrl.Key())
-                               ids[md5] = serviceUrl
-                               UrlIdsMapper.LoadOrStore(serviceUrl.Key(), md5)
-                       }
+               }
+               service := serviceURL.ServiceKey()
+               ids, found := services[service]
+               if !found {
+                       ids = make(map[string]*common.URL)
+                       services[service] = ids
+               }
+               if md5, ok := UrlIdsMapper.Load(serviceURL.Key()); ok {
+                       ids[md5.(string)] = serviceURL
+               } else {
+                       md5 := util2.Md5_16bit(serviceURL.Key())
+                       ids[md5] = serviceURL
+                       UrlIdsMapper.LoadOrStore(serviceURL.Key(), md5)
                }
        }
        // check categories size
@@ -120,11 +130,17 @@ func (adminNotifyListener) Notify(event 
*registry.ServiceEvent) {
                for category, value := range categories {
                        services, ok := 
cache.InterfaceRegistryCache.Load(category)
                        if ok {
+                               servicesMap, ok := services.(*sync.Map)
+                               if !ok {
+                                       // servicesMap type error
+                                       logger.Error("servicesMap type not 
*sync.Map")
+                                       return
+                               }
                                // iterator services key set
-                               services.(*sync.Map).Range(func(key, inner any) 
bool {
+                               servicesMap.Range(func(key, inner any) bool {
                                        _, ok := value[key.(string)]
-                                       if util2.GetInterface(key.(string)) == 
interfaceName && ok {
-                                               services.(*sync.Map).Delete(key)
+                                       if util2.GetInterface(key.(string)) == 
interfaceName && !ok {
+                                               servicesMap.Delete(key)
                                        }
                                        return true
                                })
@@ -139,18 +155,6 @@ func (adminNotifyListener) Notify(event 
*registry.ServiceEvent) {
        }
 }
 
-func getServiceInterface(url *common.URL) string {
-       path := url.Path
-       if strings.HasPrefix(path, "/") {
-               path = path[1:]
-       }
-       serviceInterface := url.GetParam(constant.InterfaceKey, path)
-       if len(serviceInterface) == 0 || constant.AnyValue == serviceInterface {
-               serviceInterface = path
-       }
-       return serviceInterface
-}
-
 func (adminNotifyListener) NotifyAll(events []*registry.ServiceEvent, f 
func()) {
        for _, event := range events {
                adminNotifyListener{}.Notify(event)
diff --git a/dubbo-admin-server/pkg/util/sync_utils.go 
b/dubbo-admin-server/pkg/util/sync_utils.go
new file mode 100644
index 0000000..1883b07
--- /dev/null
+++ b/dubbo-admin-server/pkg/util/sync_utils.go
@@ -0,0 +1,29 @@
+package util
+
+import (
+       "admin/pkg/constant"
+       "admin/pkg/model"
+       "dubbo.apache.org/dubbo-go/v3/common"
+)
+
+func URL2Provider(id string, url *common.URL) *model.Provider {
+       if url == nil {
+               return nil
+       }
+
+       return &model.Provider{
+               Entity:         model.Entity{Hash: id},
+               Service:        url.ServiceKey(),
+               Address:        url.Location,
+               Application:    url.GetParam(constant.ApplicationKey, ""),
+               URL:            url.Key(),
+               Parameters:     url.String(),
+               Dynamic:        url.GetParamBool(constant.DynamicKey, true),
+               Enabled:        url.GetParamBool(constant.EnabledKey, true),
+               Serialization:  url.GetParam(constant.SerializationKey, 
"hessian2"),
+               Timeout:        url.GetParamInt(constant.TimeoutKey, 
constant.DefaultTimeout),
+               Weight:         url.GetParamInt(constant.WeightKey, 
constant.DefaultWeight),
+               Username:       url.GetParam(constant.OwnerKey, ""),
+               RegistrySource: model.Interface,
+       }
+}
diff --git a/dubbo-admin-server/router/router.go 
b/dubbo-admin-server/router/router.go
index e2dd997..a99c68e 100644
--- a/dubbo-admin-server/router/router.go
+++ b/dubbo-admin-server/router/router.go
@@ -26,6 +26,7 @@ func InitRouter() *gin.Engine {
        router := gin.Default()
 
        router.GET("/api/dev/services", handlers.AllServices)
+       router.GET("/api/dev/service", handlers.SearchService)
 
        return router
 }

Reply via email to