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
}