Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion pkg/config/store/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
package store

import (
"os"
"strings"

"github.com/apache/dubbo-admin/pkg/config"
)

Expand All @@ -31,16 +34,53 @@ const (
Postgres Type = "postgres"
)

// DeploymentMode represents the deployment mode of the store
type DeploymentMode string

const (
// DeploymentModeSingle represents single instance deployment
DeploymentModeSingle DeploymentMode = "single"
// DeploymentModeMasterSlave represents master-slave deployment
DeploymentModeMasterSlave DeploymentMode = "master-slave"
)

// Config defines the ResourceStore configuration
type Config struct {
config.BaseConfig
// Type of Store used in Admin
Type Type `json:"type"`
Address string `json:"address"`
// DeploymentMode specifies the deployment mode (single or master-slave)
DeploymentMode DeploymentMode `json:"deploymentMode"`
// UseDBIndex forces using database-backed index (overrides auto-detection)
UseDBIndex *bool `json:"useDbIndex,omitempty"`
}

func DefaultStoreConfig() *Config {
return &Config{
Type: Memory,
Type: Memory,
DeploymentMode: detectDeploymentMode(),
UseDBIndex: nil, // Auto-detect based on deployment mode
}
}

// detectDeploymentMode detects the deployment mode from environment
func detectDeploymentMode() DeploymentMode {
mode := os.Getenv("DUBBO_ADMIN_DB_DEPLOYMENT_MODE")
if mode != "" {
mode = strings.ToLower(mode)
if mode == "master-slave" || mode == "cluster" {
return DeploymentModeMasterSlave
}
}
return DeploymentModeSingle
}

// ShouldUseDBIndex determines whether to use database-backed index
func (c *Config) ShouldUseDBIndex() bool {
if c.UseDBIndex != nil {
return *c.UseDBIndex
}
// Auto-detect: use DB index for master-slave deployment
return c.DeploymentMode == DeploymentModeMasterSlave
}
12 changes: 8 additions & 4 deletions pkg/console/service/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ import (

// SearchInstanceByIp search instance by ip
func SearchInstanceByIp(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) {
pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource](
pageData, err := manager.PageListByIndexesWithPrefix[*meshresource.InstanceResource](
ctx.ResourceManager(),
meshresource.InstanceKind,
map[string]string{
index.ByMeshIndex: req.Mesh,
index.ByMeshIndex: req.Mesh,
},
map[string]string{
index.ByInstanceIpIndex: req.Keywords,
},
req.PageReq)
Expand All @@ -72,11 +74,13 @@ func SearchInstanceByIp(ctx consolectx.Context, req *model.SearchReq) (*model.Se

// SearchInstanceByName search instance by name
func SearchInstanceByName(ctx consolectx.Context, req *model.SearchReq) (*model.SearchPaginationResult, error) {
pageData, err := manager.PageListByIndexes[*meshresource.InstanceResource](
pageData, err := manager.PageListByIndexesWithPrefix[*meshresource.InstanceResource](
ctx.ResourceManager(),
meshresource.InstanceKind,
map[string]string{
index.ByMeshIndex: req.Mesh,
index.ByMeshIndex: req.Mesh,
},
map[string]string{
index.ByInstanceNameIndex: req.Keywords,
},
req.PageReq)
Expand Down
8 changes: 5 additions & 3 deletions pkg/console/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,15 @@ func SearchServices(ctx consolectx.Context, req *model.ServiceSearchReq) (*model
}, nil
}

// SearchServicesByKeywords search services by keywords, for now only support accurate search
// SearchServicesByKeywords search services by keywords, now supports prefix search
func SearchServicesByKeywords(ctx consolectx.Context, req *model.ServiceSearchReq) (*model.SearchPaginationResult, error) {
pageData, err := manager.PageListByIndexes[*meshresource.ServiceProviderMetadataResource](
pageData, err := manager.PageListByIndexesWithPrefix[*meshresource.ServiceProviderMetadataResource](
ctx.ResourceManager(),
meshresource.ServiceProviderMetadataKind,
map[string]string{
index.ByMeshIndex: req.Mesh,
index.ByMeshIndex: req.Mesh,
},
map[string]string{
index.ByServiceProviderServiceName: req.Keywords,
},
req.PageReq,
Expand Down
37 changes: 37 additions & 0 deletions pkg/core/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ type ReadOnlyResourceManager interface {
ListByIndexes(rk model.ResourceKind, indexes map[string]string) ([]model.Resource, error)
// PageListByIndexes page list the resources with the given indexes, indexes is a map of index name and index value
PageListByIndexes(rk model.ResourceKind, indexes map[string]string, pr model.PageReq) (*model.PageData[model.Resource], error)
// ListByIndexesWithPrefix returns the resources with the given indexes and prefix indexes
ListByIndexesWithPrefix(rk model.ResourceKind, indexes map[string]string, prefixIndexes map[string]string) ([]model.Resource, error)
// PageListByIndexesWithPrefix page list the resources with the given indexes and prefix indexes
PageListByIndexesWithPrefix(rk model.ResourceKind, indexes map[string]string, prefixIndexes map[string]string, pr model.PageReq) (*model.PageData[model.Resource], error)
// PageSearchResourceByConditions page fuzzy search resource by conditions, conditions cannot be empty
// TODO support multiple conditions
PageSearchResourceByConditions(rk model.ResourceKind, conditions []string, pr model.PageReq) (*model.PageData[model.Resource], error)
Expand Down Expand Up @@ -128,6 +132,39 @@ func (rm *resourcesManager) PageListByIndexes(
return pageData, nil
}

func (rm *resourcesManager) ListByIndexesWithPrefix(
rk model.ResourceKind,
indexes map[string]string,
prefixIndexes map[string]string) ([]model.Resource, error) {

rs, err := rm.storeRouter.ResourceKindRoute(rk)
if err != nil {
return nil, err
}
resources, err := rs.ListByIndexesWithPrefix(indexes, prefixIndexes)
if err != nil {
return nil, err
}
return resources, nil
}

func (rm *resourcesManager) PageListByIndexesWithPrefix(
rk model.ResourceKind,
indexes map[string]string,
prefixIndexes map[string]string,
pr model.PageReq) (*model.PageData[model.Resource], error) {

rs, err := rm.storeRouter.ResourceKindRoute(rk)
if err != nil {
return nil, err
}
pageData, err := rs.PageListByIndexesWithPrefix(indexes, prefixIndexes, pr)
if err != nil {
return nil, err
}
return pageData, nil
}

func (rm *resourcesManager) PageSearchResourceByConditions(rk model.ResourceKind, conditions []string, pr model.PageReq) (*model.PageData[model.Resource], error) {
//TODO implement me
panic("implement me")
Expand Down
56 changes: 56 additions & 0 deletions pkg/core/manager/manager_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,59 @@ func PageSearchResourceByConditions[T model.Resource](
}
return newPageData, nil
}

// ListByIndexesWithPrefix is a helper function of ResourceManager.ListByIndexesWithPrefix
func ListByIndexesWithPrefix[T model.Resource](
rm ReadOnlyResourceManager,
rk model.ResourceKind,
indexes map[string]string,
prefixIndexes map[string]string) ([]T, error) {

resources, err := rm.ListByIndexesWithPrefix(rk, indexes, prefixIndexes)
if err != nil {
return nil, err
}

typedResources := make([]T, len(resources))
for i, resource := range resources {
typedResource, ok := resource.(T)
if !ok {
return nil, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name())
}
typedResources[i] = typedResource
}

return typedResources, nil
}

// PageListByIndexesWithPrefix is a helper function of ResourceManager.PageListByIndexesWithPrefix
func PageListByIndexesWithPrefix[T model.Resource](
rm ReadOnlyResourceManager,
rk model.ResourceKind,
indexes map[string]string,
prefixIndexes map[string]string,
pr model.PageReq) (*model.PageData[T], error) {

pageData, err := rm.PageListByIndexesWithPrefix(rk, indexes, prefixIndexes, pr)
if err != nil {
return nil, err
}

typedResources := make([]T, len(pageData.Data))
for i, resource := range pageData.Data {
typedResource, ok := resource.(T)
if !ok {
return nil, bizerror.NewAssertionError(rk, reflect.TypeOf(typedResource).Name())
}
typedResources[i] = typedResource
}
newPageData := &model.PageData[T]{
Pagination: model.Pagination{
Total: pageData.Total,
PageOffset: pageData.PageOffset,
PageSize: pageData.PageSize,
},
Data: typedResources,
}
return newPageData, nil
}
5 changes: 5 additions & 0 deletions pkg/core/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ type ResourceStore interface {
ListByIndexes(indexes map[string]string) ([]model.Resource, error)
// PageListByIndexes list resources by indexes pageable, indexes is map of index name and index value
PageListByIndexes(indexes map[string]string, pq model.PageReq) (*model.PageData[model.Resource], error)
// ListByIndexesWithPrefix list resources by indexes with prefix matching support
// prefixIndexes is map of index name and prefix value
ListByIndexesWithPrefix(indexes map[string]string, prefixIndexes map[string]string) ([]model.Resource, error)
// PageListByIndexesWithPrefix list resources by indexes with prefix matching support, pageable
PageListByIndexesWithPrefix(indexes map[string]string, prefixIndexes map[string]string, pq model.PageReq) (*model.PageData[model.Resource], error)
}

// ManagedResourceStore includes both functional interfaces and lifecycle interfaces
Expand Down
Loading
Loading