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

robocanic pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-admin.git


The following commit(s) were added to refs/heads/develop by this push:
     new 3ff3bbd8 feat: support multi types of ResourceStore (#1310)
3ff3bbd8 is described below

commit 3ff3bbd8b4197e3c551de6d218f79224b02570b1
Author: robb <[email protected]>
AuthorDate: Sun Aug 10 17:25:59 2025 +0800

    feat: support multi types of ResourceStore (#1310)
    
    Development stage, mergo first
---
 api/mesh/v1alpha1/traffic_helper.go                |   9 +-
 go.mod                                             |   1 -
 pkg/config/store/config.go                         |   4 +-
 pkg/console/service/application.go                 |   9 +-
 pkg/core/bootstrap/bootstrap.go                    |  15 +-
 pkg/core/discovery/component.go                    |   4 -
 pkg/core/engine/component.go                       |   5 -
 pkg/core/manager/component.go                      |   8 +-
 pkg/core/manager/customizable_manager.go           |  68 +-----
 pkg/core/manager/manager.go                        |  90 ++++++--
 .../apis/mesh/v1alpha1/affinityroute_types.go      |  46 ++--
 .../apis/mesh/v1alpha1/application_types.go        |  46 ++--
 .../apis/mesh/v1alpha1/conditionroute_types.go     |  46 ++--
 .../apis/mesh/v1alpha1/dynamicconfig_types.go      |  46 ++--
 .../resource/apis/mesh/v1alpha1/instance_types.go  |  46 ++--
 .../resource/apis/mesh/v1alpha1/mapping_types.go   |  46 ++--
 .../resource/apis/mesh/v1alpha1/service_types.go   |  46 ++--
 .../resource/apis/mesh/v1alpha1/tagroute_types.go  |  46 ++--
 .../resource/apis/system/v1alpha1/config_types.go  |  46 ++--
 .../apis/system/v1alpha1/datasource_types.go       |  46 ++--
 .../resource/apis/system/v1alpha1/secret_types.go  |  46 ++--
 .../resource/apis/system/v1alpha1/zone_types.go    |  46 ++--
 .../apis/system/v1alpha1/zoneinsight_types.go      |  46 ++--
 pkg/core/resource/model/page.go                    |  15 ++
 pkg/core/resource/model/registry.go                |  48 +++++
 pkg/core/resource/model/resource.go                |  44 ++--
 pkg/core/runtime/component.go                      |  37 ++--
 pkg/core/runtime/registry.go                       |  75 +++----
 pkg/core/store/component.go                        |  79 +++++--
 pkg/core/store/indexregistry.go                    |  60 ++++++
 pkg/core/store/options.go                          |  16 +-
 pkg/core/store/store.go                            |  14 +-
 pkg/core/store/storeregistry.go                    |  63 ++++++
 pkg/store/memory/memory.go                         |   1 -
 tools/resourcegen/main.go                          | 237 +++++++++++++++++++++
 tools/resourcegen/util/util.go                     | 135 ++++++++++++
 36 files changed, 1110 insertions(+), 525 deletions(-)

diff --git a/api/mesh/v1alpha1/traffic_helper.go 
b/api/mesh/v1alpha1/traffic_helper.go
index 43409908..903b6671 100644
--- a/api/mesh/v1alpha1/traffic_helper.go
+++ b/api/mesh/v1alpha1/traffic_helper.go
@@ -20,19 +20,18 @@ package v1alpha1
 import (
        "strings"
 
+       "github.com/apache/dubbo-admin/pkg/core/consts"
        "github.com/dubbogo/gost/encoding/yaml"
-
-       "github.com/apache/dubbo-kubernetes/pkg/core/consts"
 )
 
 // Application 流量管控相关的基础label
 const (
-       ApplicationLabel = "dubbo.io/application"
+       ApplicationLabel    = "dubbo.io/application"
        ServiceLabel        = "dubbo.io/service"
        IDLabel             = "dubbo.io/id"
        ServiceVersionLabel = "dubbo.io/serviceVersion"
-       ServiceGroupLabel = "dubbo.io/serviceGroup"
-       RevisionLabel     = "dubbo.io/revision"
+       ServiceGroupLabel   = "dubbo.io/serviceGroup"
+       RevisionLabel       = "dubbo.io/revision"
 )
 
 type Base struct {
diff --git a/go.mod b/go.mod
index a2d81b4b..4d300bc6 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,6 @@ require (
        github.com/AlecAivazis/survey/v2 v2.3.7
        github.com/Masterminds/semver/v3 v3.2.1
        github.com/Microsoft/go-winio v0.6.2
-       github.com/apache/dubbo-kubernetes v0.1.4
        github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
        github.com/bakito/go-log-logr-adapter v0.0.2
        github.com/buildpacks/pack v0.30.0
diff --git a/pkg/config/store/config.go b/pkg/config/store/config.go
index 6e330e5b..6797e83d 100644
--- a/pkg/config/store/config.go
+++ b/pkg/config/store/config.go
@@ -29,10 +29,10 @@ const (
        Memory Type = "memory"
 )
 
-// Config defines Resource Store configuration
+// Config defines the ResourceStore configuration
 type Config struct {
        config.BaseConfig
-       // Type of Store used in the Control Plane. Can be either "kubernetes", 
"postgres" or "memory"
+       // Type of Store used in Admin
        Type    Type   `json:"type"`
        Address string `json:"address"`
 }
diff --git a/pkg/console/service/application.go 
b/pkg/console/service/application.go
index 6fb8f2bb..d8e0c138 100644
--- a/pkg/console/service/application.go
+++ b/pkg/console/service/application.go
@@ -28,19 +28,22 @@ import (
        "github.com/apache/dubbo-admin/pkg/console/context"
        "github.com/apache/dubbo-admin/pkg/console/model"
        "github.com/apache/dubbo-admin/pkg/core/store"
+
+       "github.com/apache/dubbo-kubernetes/pkg/core/resources/apis/mesh"
 )
 
 func GetApplicationDetail(ctx context.Context, req 
*model.ApplicationDetailReq) (*model.ApplicationDetailResp, error) {
        manager := ctx.ResourceManager()
-       dataplaneList := &mesh.DataplaneResourceList{}
+       instanceList := &mesh.DataplaneResourceList{}
 
-       if err := manager.List(ctx.AppContext(), dataplaneList, 
store.ListByApplication(req.AppName)); err != nil {
+       manager.ListPageByKey()
+       if err := manager.List(ctx.AppContext(), instanceList, 
store.ListByApplication(req.AppName)); err != nil {
                return nil, err
        }
 
        revisions := make(map[string]*mesh.MetaDataResource, 0)
        applicationDetail := model.NewApplicationDetail()
-       for _, dataplane := range dataplaneList.Items {
+       for _, dataplane := range instanceList.Items {
                if strings.Split(dataplane.GetMeta().GetName(), 
constant.KeySeparator)[1] == "0" {
                        continue
                }
diff --git a/pkg/core/bootstrap/bootstrap.go b/pkg/core/bootstrap/bootstrap.go
index 84270d31..1c8cd63b 100644
--- a/pkg/core/bootstrap/bootstrap.go
+++ b/pkg/core/bootstrap/bootstrap.go
@@ -65,15 +65,14 @@ func Bootstrap(appCtx context.Context, cfg app.AdminConfig) 
(runtime.Runtime, er
 }
 
 func initResourceStore(cfg app.AdminConfig, builder *runtime.Builder) error {
-       storeCfg := cfg.Store
-       comp, err := runtime.ComponentRegistry().ResourceStore(storeCfg.Type)
+       comp, err := runtime.ComponentRegistry().ResourceStore()
        if err != nil {
                return errors.Wrapf(err, "could not retrieve resource store %s 
component", cfg.Store.Type)
        }
        return initAndActivateComponent(builder, comp)
 }
 func initResourceManager(builder *runtime.Builder) error {
-       comp, err := 
runtime.ComponentRegistry().ResourceManager(runtime.ResourceManager)
+       comp, err := runtime.ComponentRegistry().ResourceManager()
        if err != nil {
                return err
        }
@@ -81,7 +80,7 @@ func initResourceManager(builder *runtime.Builder) error {
 }
 
 func initializeConsole(builder *runtime.Builder) error {
-       comp, err := runtime.ComponentRegistry().Console(runtime.Console)
+       comp, err := runtime.ComponentRegistry().Console()
        if err != nil {
                return err
        }
@@ -89,7 +88,7 @@ func initializeConsole(builder *runtime.Builder) error {
 }
 
 func initializeResourceDiscovery(builder *runtime.Builder) error {
-       comp, err := 
runtime.ComponentRegistry().ResourceDiscovery(runtime.ResourceDiscovery)
+       comp, err := runtime.ComponentRegistry().ResourceDiscovery()
        if err != nil {
                return err
        }
@@ -97,7 +96,7 @@ func initializeResourceDiscovery(builder *runtime.Builder) 
error {
 }
 
 func initializeResourceEngine(builder *runtime.Builder) error {
-       comp, err := 
runtime.ComponentRegistry().ResourceEngine(runtime.ResourceEngine)
+       comp, err := runtime.ComponentRegistry().ResourceEngine()
        if err != nil {
                return err
        }
@@ -105,7 +104,7 @@ func initializeResourceEngine(builder *runtime.Builder) 
error {
 }
 
 func initializeDiagnoticsServer(builder *runtime.Builder) error {
-       comp, err := 
runtime.ComponentRegistry().Get(diagnostics.DiagnosticsServer, 
runtime.DefaultComponentSubType)
+       comp, err := 
runtime.ComponentRegistry().Get(diagnostics.DiagnosticsServer)
        if err != nil {
                return err
        }
@@ -113,7 +112,7 @@ func initializeDiagnoticsServer(builder *runtime.Builder) 
error {
 }
 
 func initAndActivateComponent(builder *runtime.Builder, comp 
runtime.Component) error {
-       logger.Infof("initializing %s of %s ...", comp.SubType(), comp.Type())
+       logger.Infof("initializing %s ...", comp.Type())
        if err := comp.Init(builder); err != nil {
                return err
        }
diff --git a/pkg/core/discovery/component.go b/pkg/core/discovery/component.go
index e52f0c86..28542dc7 100644
--- a/pkg/core/discovery/component.go
+++ b/pkg/core/discovery/component.go
@@ -19,10 +19,6 @@ func (b *BaseResourceDiscoveryComponent) Type() 
runtime.ComponentType {
        return runtime.ResourceDiscovery
 }
 
-func (b *BaseResourceDiscoveryComponent) SubType() runtime.ComponentSubType {
-       panic("SubType() must be implemented by concrete 
BaseResourceDiscoveryComponent")
-}
-
 func (b *BaseResourceDiscoveryComponent) Order() int {
        return math.MaxInt
 }
diff --git a/pkg/core/engine/component.go b/pkg/core/engine/component.go
index a656fff9..5a4f0c95 100644
--- a/pkg/core/engine/component.go
+++ b/pkg/core/engine/component.go
@@ -19,11 +19,6 @@ func (b BaseResourceEngineComponent) Type() 
runtime.ComponentType {
        return runtime.ResourceEngine
 }
 
-func (b BaseResourceEngineComponent) SubType() runtime.ComponentSubType {
-       panic("SubType() must be implemented by concrete 
BaseResourceEngineComponent")
-
-}
-
 func (b BaseResourceEngineComponent) Order() int {
        return math.MaxInt
 }
diff --git a/pkg/core/manager/component.go b/pkg/core/manager/component.go
index 990a7dc8..8a0eb0e3 100644
--- a/pkg/core/manager/component.go
+++ b/pkg/core/manager/component.go
@@ -28,10 +28,6 @@ func (r *resourceManagerComponent) Type() 
runtime.ComponentType {
        return runtime.ResourceManager
 }
 
-func (r *resourceManagerComponent) SubType() runtime.ComponentSubType {
-       return runtime.ResourceManager
-}
-
 func (r *resourceManagerComponent) Order() int {
        return math.MaxInt
 }
@@ -41,9 +37,7 @@ func (r *resourceManagerComponent) Init(ctx 
runtime.BuilderContext) error {
        if err != nil {
                return errors.Wrap(err, "failed to init resource manager")
        }
-       r.rm = &resourcesManager{
-               Store: rsc.(store.Component).ResourceStore(),
-       }
+       r.rm = NewResourceManager(rsc.(store.Router))
        return nil
 }
 
diff --git a/pkg/core/manager/customizable_manager.go 
b/pkg/core/manager/customizable_manager.go
index f17dd960..cf46704c 100644
--- a/pkg/core/manager/customizable_manager.go
+++ b/pkg/core/manager/customizable_manager.go
@@ -18,78 +18,14 @@
 package manager
 
 import (
-       "context"
-
        "github.com/apache/dubbo-admin/pkg/core/resource/model"
-       "github.com/apache/dubbo-admin/pkg/core/store"
 )
 
 type ResourceManagerWrapper = func(delegate ResourceManager) ResourceManager
 
 type CustomizableResourceManager interface {
        ResourceManager
-       Customize(model.ResourceType, ResourceManager)
-       ResourceManager(model.ResourceType) ResourceManager
+       Customize(model.ResourceKind, ResourceManager)
+       ResourceManager(model.ResourceKind) ResourceManager
        WrapAll(ResourceManagerWrapper)
 }
-
-func NewCustomizableResourceManager(defaultManager ResourceManager, 
customManagers map[model.ResourceType]ResourceManager) 
CustomizableResourceManager {
-       if customManagers == nil {
-               customManagers = map[model.ResourceType]ResourceManager{}
-       }
-       return &customizableResourceManager{
-               defaultManager: defaultManager,
-               customManagers: customManagers,
-       }
-}
-
-var _ CustomizableResourceManager = &customizableResourceManager{}
-
-type customizableResourceManager struct {
-       defaultManager ResourceManager
-       customManagers map[model.ResourceType]ResourceManager
-}
-
-// Customize installs a new manager for the given type, overwriting any
-// existing manager for that type.
-func (m *customizableResourceManager) Customize(resourceType 
model.ResourceType, manager ResourceManager) {
-       m.customManagers[resourceType] = manager
-}
-
-func (m *customizableResourceManager) Get(ctx context.Context, resource 
model.Resource, fs ...store.GetOptionsFunc) error {
-       return m.ResourceManager(resource.Descriptor().Name).Get(ctx, resource, 
fs...)
-}
-
-func (m *customizableResourceManager) List(ctx context.Context, list 
model.ResourceList, fs ...store.ListOptionsFunc) error {
-       return m.ResourceManager(list.GetItemType()).List(ctx, list, fs...)
-}
-
-func (m *customizableResourceManager) Create(ctx context.Context, resource 
model.Resource, fs ...store.CreateOptionsFunc) error {
-       return m.ResourceManager(resource.Descriptor().Name).Create(ctx, 
resource, fs...)
-}
-
-func (m *customizableResourceManager) Delete(ctx context.Context, resource 
model.Resource, fs ...store.DeleteOptionsFunc) error {
-       return m.ResourceManager(resource.Descriptor().Name).Delete(ctx, 
resource, fs...)
-}
-
-func (m *customizableResourceManager) DeleteAll(ctx context.Context, list 
model.ResourceList, fs ...store.DeleteAllOptionsFunc) error {
-       return m.ResourceManager(list.GetItemType()).DeleteAll(ctx, list, fs...)
-}
-
-func (m *customizableResourceManager) Update(ctx context.Context, resource 
model.Resource, fs ...store.UpdateOptionsFunc) error {
-       return m.ResourceManager(resource.Descriptor().Name).Update(ctx, 
resource, fs...)
-}
-
-func (m *customizableResourceManager) ResourceManager(typ model.ResourceType) 
ResourceManager {
-       if customManager, ok := m.customManagers[typ]; ok {
-               return customManager
-       }
-       return m.defaultManager
-}
-
-func (m *customizableResourceManager) WrapAll(wrapper ResourceManagerWrapper) {
-       m.defaultManager = wrapper(m.defaultManager)
-       for key, manager := range m.customManagers {
-               m.customManagers[key] = wrapper(manager)
-       }
-}
diff --git a/pkg/core/manager/manager.go b/pkg/core/manager/manager.go
index 6025b281..e56c9b6e 100644
--- a/pkg/core/manager/manager.go
+++ b/pkg/core/manager/manager.go
@@ -22,17 +22,19 @@ import (
        "fmt"
        "time"
 
-       "github.com/duke-git/lancet/v2/slice"
-
        "github.com/apache/dubbo-admin/pkg/core/resource/model"
        "github.com/apache/dubbo-admin/pkg/core/store"
+       "github.com/duke-git/lancet/v2/slice"
 )
 
 type ReadOnlyResourceManager interface {
        // GetByKey returns the resource with the given resource key
-       GetByKey(rk string) (r model.Resource, exist bool, err error)
-       // ListPageByKey page list the resources with the given resource key
-       ListPageByKey(rk string, pq model.PageQuery) ([]model.Resource, 
model.Pagination)
+       GetByKey(rk model.ResourceKind, key string) (r model.Resource, exist 
bool, err error)
+       // ListByIndex returns the resource with the given index name
+       ListByIndex(rk model.ResourceKind, indexName string, indexKey 
interface{}) ([]model.Resource, error)
+       // ListPageByIndex page list the resources with the given index
+       ListPageByIndex(rk model.ResourceKind, indexName string,
+               indexValue interface{}, pq model.PageQuery) ([]model.Resource, 
model.Pagination, error)
 }
 
 type WriteOnlyResourceManager interface {
@@ -43,7 +45,7 @@ type WriteOnlyResourceManager interface {
        // Upsert upserts the resource
        Upsert(r model.Resource) error
        // DeleteByKey deletes the resource with the given resource key
-       DeleteByKey(key string) error
+       DeleteByKey(rk model.ResourceKind, key string) error
 }
 
 type ResourceManager interface {
@@ -52,56 +54,98 @@ type ResourceManager interface {
        WriteOnlyResourceManager
 }
 
-func NewResourceManager(store store.ResourceStore) ResourceManager {
+func NewResourceManager(router store.Router) ResourceManager {
        return &resourcesManager{
-               Store: store,
+               StoreRouter: router,
        }
 }
 
 var _ ResourceManager = &resourcesManager{}
 
 type resourcesManager struct {
-       Store store.ResourceStore
+       StoreRouter store.Router
 }
 
-func (rm *resourcesManager) GetByKey(key string) (r model.Resource, exist 
bool, err error) {
-       item, exist, err := rm.Store.GetByKey(key)
+func (rm *resourcesManager) GetByKey(rk model.ResourceKind, key string) (r 
model.Resource, exist bool, err error) {
+       rs, err := rm.StoreRouter.ResourceKindRoute(rk)
+       if err != nil {
+               return nil, false, err
+       }
+       item, exist, err := rs.GetByKey(key)
        return item.(model.Resource), exist, err
 }
 
-func (rm *resourcesManager) ListPageByKey(key string, pageQuery 
model.PageQuery) ([]model.Resource, model.Pagination) {
-       items, p := rm.Store.ListPageByKey(key, pageQuery)
-       rs := slice.Map(items, func(_ int, item interface{}) model.Resource {
+func (rm *resourcesManager) ListByIndex(rk model.ResourceKind, indexName 
string, indexKey interface{}) ([]model.Resource, error) {
+       rs, err := rm.StoreRouter.ResourceKindRoute(rk)
+       if err != nil {
+               return nil, err
+       }
+       objList, err := rs.Index(indexName, indexKey)
+       if err != nil {
+               return nil, err
+       }
+       resources := slice.Map(objList, func(_ int, item interface{}) 
model.Resource {
                return item.(model.Resource)
        })
-       return rs, p
+       return resources, nil
+}
+
+func (rm *resourcesManager) ListPageByIndex(
+       rk model.ResourceKind,
+       indexName string,
+       indexValue interface{},
+       pageQuery model.PageQuery) ([]model.Resource, model.Pagination, error) {
+       rs, err := rm.StoreRouter.ResourceKindRoute(rk)
+       if err != nil {
+               return nil, model.Pagination{}, err
+       }
+       items, p, err := rs.ListPageByIndex(indexName, indexValue, pageQuery)
+       if err != nil {
+               return nil, p, err
+       }
+       rsList := slice.Map(items, func(_ int, item interface{}) model.Resource 
{
+               return item.(model.Resource)
+       })
+       return rsList, p, nil
 }
 
 func (rm *resourcesManager) Add(r model.Resource) error {
-       return rm.Store.Add(r)
+       rs, err := rm.StoreRouter.ResourceRoute(r)
+       if err != nil {
+               return err
+       }
+       return rs.Add(r)
 }
 
 func (rm *resourcesManager) Update(r model.Resource) error {
-       return rm.Store.Update(r)
+       rs, err := rm.StoreRouter.ResourceRoute(r)
+       if err != nil {
+               return err
+       }
+       return rs.Update(r)
 }
 
 func (rm *resourcesManager) Upsert(r model.Resource) error {
-       if _, exists, _ := rm.Store.GetByKey(r.GetResourceKey()); exists {
+       if _, exists, _ := rm.GetByKey(r.ResourceKind(), r.ResourceKey()); 
exists {
                return rm.Update(r)
        } else {
                return rm.Add(r)
        }
 }
 
-func (rm *resourcesManager) DeleteByKey(key string) error {
-       r, exists, err := rm.Store.GetByKey(key)
-       if exists && err == nil {
-               return rm.Store.Delete(r)
+func (rm *resourcesManager) DeleteByKey(rk model.ResourceKind, key string) 
error {
+       rs, err := rm.StoreRouter.ResourceKindRoute(rk)
+       if err != nil {
+               return err
        }
+       r, exists, err := rm.GetByKey(rk, key)
        if err != nil {
                return fmt.Errorf("failed to get resource %s: %s", key, err)
        }
-       return fmt.Errorf("resource %s does not exist", key)
+       if !exists {
+               return fmt.Errorf("%s %s does not exist", rk, key)
+       }
+       return rs.Delete(r)
 }
 
 type ConflictRetry struct {
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go
index 3ac8bc57..7a932c6a 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/affinityroute_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const AffinityRouteKind = "AffinityRoute"
+const AffinityRouteKind coremodel.ResourceKind = "AffinityRoute"
+
+func init() {
+       coremodel.RegisterResourceKind(AffinityRouteKind)
+}
 
 type AffinityRouteResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type AffinityRouteResourceList struct {
        Items           []AffinityRouteResource `json:"items"`
 }
 
-func (r *AffinityRouteResource) GetKind() string {
-       return r.Kind
+func (r *AffinityRouteResource) ResourceKind() coremodel.ResourceKind {
+       return AffinityRouteKind
 }
 
-func (r *AffinityRouteResource) GetMesh() string {
+func (r *AffinityRouteResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *AffinityRouteResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *AffinityRouteResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *AffinityRouteResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *AffinityRouteResource) GetMeta() metav1.ObjectMeta {
+func (r *AffinityRouteResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *AffinityRouteResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *AffinityRouteResource) GetSpec() coremodel.ResourceSpec {
+func (r *AffinityRouteResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *AffinityRouteResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.AffinityRoute); ok {
-               r.Spec = spec
-               return nil
+func NewAffinityRouteResource(name string, mesh string, apiVersion string) 
*AffinityRouteResource {
+       return &AffinityRouteResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(AffinityRouteKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/application_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/application_types.go
index 13c821b9..0a2b03ec 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/application_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/application_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Namespaced
 
-const ApplicationKind = "Application"
+const ApplicationKind coremodel.ResourceKind = "Application"
+
+func init() {
+       coremodel.RegisterResourceKind(ApplicationKind)
+}
 
 type ApplicationResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ApplicationResourceList struct {
        Items           []ApplicationResource `json:"items"`
 }
 
-func (r *ApplicationResource) GetKind() string {
-       return r.Kind
+func (r *ApplicationResource) ResourceKind() coremodel.ResourceKind {
+       return ApplicationKind
 }
 
-func (r *ApplicationResource) GetMesh() string {
+func (r *ApplicationResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ApplicationResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ApplicationResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ApplicationResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ApplicationResource) GetMeta() metav1.ObjectMeta {
+func (r *ApplicationResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ApplicationResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ApplicationResource) GetSpec() coremodel.ResourceSpec {
+func (r *ApplicationResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ApplicationResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.Application); ok {
-               r.Spec = spec
-               return nil
+func NewApplicationResource(name string, mesh string, apiVersion string) 
*ApplicationResource {
+       return &ApplicationResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ApplicationKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go
index 43e70709..c118cd50 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/conditionroute_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const ConditionRouteKind = "ConditionRoute"
+const ConditionRouteKind coremodel.ResourceKind = "ConditionRoute"
+
+func init() {
+       coremodel.RegisterResourceKind(ConditionRouteKind)
+}
 
 type ConditionRouteResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ConditionRouteResourceList struct {
        Items           []ConditionRouteResource `json:"items"`
 }
 
-func (r *ConditionRouteResource) GetKind() string {
-       return r.Kind
+func (r *ConditionRouteResource) ResourceKind() coremodel.ResourceKind {
+       return ConditionRouteKind
 }
 
-func (r *ConditionRouteResource) GetMesh() string {
+func (r *ConditionRouteResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ConditionRouteResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ConditionRouteResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ConditionRouteResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ConditionRouteResource) GetMeta() metav1.ObjectMeta {
+func (r *ConditionRouteResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ConditionRouteResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ConditionRouteResource) GetSpec() coremodel.ResourceSpec {
+func (r *ConditionRouteResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ConditionRouteResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.ConditionRoute); ok {
-               r.Spec = spec
-               return nil
+func NewConditionRouteResource(name string, mesh string, apiVersion string) 
*ConditionRouteResource {
+       return &ConditionRouteResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ConditionRouteKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go
index a639b8e7..9838fdc8 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/dynamicconfig_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const DynamicConfigKind = "DynamicConfig"
+const DynamicConfigKind coremodel.ResourceKind = "DynamicConfig"
+
+func init() {
+       coremodel.RegisterResourceKind(DynamicConfigKind)
+}
 
 type DynamicConfigResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type DynamicConfigResourceList struct {
        Items           []DynamicConfigResource `json:"items"`
 }
 
-func (r *DynamicConfigResource) GetKind() string {
-       return r.Kind
+func (r *DynamicConfigResource) ResourceKind() coremodel.ResourceKind {
+       return DynamicConfigKind
 }
 
-func (r *DynamicConfigResource) GetMesh() string {
+func (r *DynamicConfigResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *DynamicConfigResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *DynamicConfigResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *DynamicConfigResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *DynamicConfigResource) GetMeta() metav1.ObjectMeta {
+func (r *DynamicConfigResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *DynamicConfigResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *DynamicConfigResource) GetSpec() coremodel.ResourceSpec {
+func (r *DynamicConfigResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *DynamicConfigResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.DynamicConfig); ok {
-               r.Spec = spec
-               return nil
+func NewDynamicConfigResource(name string, mesh string, apiVersion string) 
*DynamicConfigResource {
+       return &DynamicConfigResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(DynamicConfigKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go
index 05bd3f11..a71b253b 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/instance_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Namespaced
 
-const InstanceKind = "Instance"
+const InstanceKind coremodel.ResourceKind = "Instance"
+
+func init() {
+       coremodel.RegisterResourceKind(InstanceKind)
+}
 
 type InstanceResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type InstanceResourceList struct {
        Items           []InstanceResource `json:"items"`
 }
 
-func (r *InstanceResource) GetKind() string {
-       return r.Kind
+func (r *InstanceResource) ResourceKind() coremodel.ResourceKind {
+       return InstanceKind
 }
 
-func (r *InstanceResource) GetMesh() string {
+func (r *InstanceResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *InstanceResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *InstanceResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *InstanceResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *InstanceResource) GetMeta() metav1.ObjectMeta {
+func (r *InstanceResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *InstanceResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *InstanceResource) GetSpec() coremodel.ResourceSpec {
+func (r *InstanceResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *InstanceResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.Instance); ok {
-               r.Spec = spec
-               return nil
+func NewInstanceResource(name string, mesh string, apiVersion string) 
*InstanceResource {
+       return &InstanceResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(InstanceKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go
index 06b159d7..bf194f27 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/mapping_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Namespaced
 
-const MappingKind = "Mapping"
+const MappingKind coremodel.ResourceKind = "Mapping"
+
+func init() {
+       coremodel.RegisterResourceKind(MappingKind)
+}
 
 type MappingResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type MappingResourceList struct {
        Items           []MappingResource `json:"items"`
 }
 
-func (r *MappingResource) GetKind() string {
-       return r.Kind
+func (r *MappingResource) ResourceKind() coremodel.ResourceKind {
+       return MappingKind
 }
 
-func (r *MappingResource) GetMesh() string {
+func (r *MappingResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *MappingResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *MappingResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *MappingResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *MappingResource) GetMeta() metav1.ObjectMeta {
+func (r *MappingResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *MappingResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *MappingResource) GetSpec() coremodel.ResourceSpec {
+func (r *MappingResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *MappingResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.Mapping); ok {
-               r.Spec = spec
-               return nil
+func NewMappingResource(name string, mesh string, apiVersion string) 
*MappingResource {
+       return &MappingResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(MappingKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/service_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/service_types.go
index e44661e3..f3abeb28 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/service_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/service_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Namespaced
 
-const ServiceKind = "Service"
+const ServiceKind coremodel.ResourceKind = "Service"
+
+func init() {
+       coremodel.RegisterResourceKind(ServiceKind)
+}
 
 type ServiceResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ServiceResourceList struct {
        Items           []ServiceResource `json:"items"`
 }
 
-func (r *ServiceResource) GetKind() string {
-       return r.Kind
+func (r *ServiceResource) ResourceKind() coremodel.ResourceKind {
+       return ServiceKind
 }
 
-func (r *ServiceResource) GetMesh() string {
+func (r *ServiceResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ServiceResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ServiceResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ServiceResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ServiceResource) GetMeta() metav1.ObjectMeta {
+func (r *ServiceResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ServiceResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ServiceResource) GetSpec() coremodel.ResourceSpec {
+func (r *ServiceResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ServiceResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.Service); ok {
-               r.Spec = spec
-               return nil
+func NewServiceResource(name string, mesh string, apiVersion string) 
*ServiceResource {
+       return &ServiceResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ServiceKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go 
b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go
index e195f5e6..516c1643 100644
--- a/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go
+++ b/pkg/core/resource/apis/mesh/v1alpha1/tagroute_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const TagRouteKind = "TagRoute"
+const TagRouteKind coremodel.ResourceKind = "TagRoute"
+
+func init() {
+       coremodel.RegisterResourceKind(TagRouteKind)
+}
 
 type TagRouteResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type TagRouteResourceList struct {
        Items           []TagRouteResource `json:"items"`
 }
 
-func (r *TagRouteResource) GetKind() string {
-       return r.Kind
+func (r *TagRouteResource) ResourceKind() coremodel.ResourceKind {
+       return TagRouteKind
 }
 
-func (r *TagRouteResource) GetMesh() string {
+func (r *TagRouteResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *TagRouteResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *TagRouteResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *TagRouteResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *TagRouteResource) GetMeta() metav1.ObjectMeta {
+func (r *TagRouteResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *TagRouteResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *TagRouteResource) GetSpec() coremodel.ResourceSpec {
+func (r *TagRouteResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *TagRouteResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*meshproto.TagRoute); ok {
-               r.Spec = spec
-               return nil
+func NewTagRouteResource(name string, mesh string, apiVersion string) 
*TagRouteResource {
+       return &TagRouteResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(TagRouteKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/system/v1alpha1/config_types.go 
b/pkg/core/resource/apis/system/v1alpha1/config_types.go
index fd57d660..2d6f2328 100644
--- a/pkg/core/resource/apis/system/v1alpha1/config_types.go
+++ b/pkg/core/resource/apis/system/v1alpha1/config_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const ConfigKind = "Config"
+const ConfigKind coremodel.ResourceKind = "Config"
+
+func init() {
+       coremodel.RegisterResourceKind(ConfigKind)
+}
 
 type ConfigResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ConfigResourceList struct {
        Items           []ConfigResource `json:"items"`
 }
 
-func (r *ConfigResource) GetKind() string {
-       return r.Kind
+func (r *ConfigResource) ResourceKind() coremodel.ResourceKind {
+       return ConfigKind
 }
 
-func (r *ConfigResource) GetMesh() string {
+func (r *ConfigResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ConfigResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ConfigResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ConfigResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ConfigResource) GetMeta() metav1.ObjectMeta {
+func (r *ConfigResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ConfigResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ConfigResource) GetSpec() coremodel.ResourceSpec {
+func (r *ConfigResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ConfigResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*systemproto.Config); ok {
-               r.Spec = spec
-               return nil
+func NewConfigResource(name string, mesh string, apiVersion string) 
*ConfigResource {
+       return &ConfigResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ConfigKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/system/v1alpha1/datasource_types.go 
b/pkg/core/resource/apis/system/v1alpha1/datasource_types.go
index 87b962d0..5788de8b 100644
--- a/pkg/core/resource/apis/system/v1alpha1/datasource_types.go
+++ b/pkg/core/resource/apis/system/v1alpha1/datasource_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const DataSourceKind = "DataSource"
+const DataSourceKind coremodel.ResourceKind = "DataSource"
+
+func init() {
+       coremodel.RegisterResourceKind(DataSourceKind)
+}
 
 type DataSourceResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type DataSourceResourceList struct {
        Items           []DataSourceResource `json:"items"`
 }
 
-func (r *DataSourceResource) GetKind() string {
-       return r.Kind
+func (r *DataSourceResource) ResourceKind() coremodel.ResourceKind {
+       return DataSourceKind
 }
 
-func (r *DataSourceResource) GetMesh() string {
+func (r *DataSourceResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *DataSourceResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *DataSourceResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *DataSourceResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *DataSourceResource) GetMeta() metav1.ObjectMeta {
+func (r *DataSourceResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *DataSourceResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *DataSourceResource) GetSpec() coremodel.ResourceSpec {
+func (r *DataSourceResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *DataSourceResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*systemproto.DataSource); ok {
-               r.Spec = spec
-               return nil
+func NewDataSourceResource(name string, mesh string, apiVersion string) 
*DataSourceResource {
+       return &DataSourceResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(DataSourceKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/system/v1alpha1/secret_types.go 
b/pkg/core/resource/apis/system/v1alpha1/secret_types.go
index dc2d9702..fc356a8f 100644
--- a/pkg/core/resource/apis/system/v1alpha1/secret_types.go
+++ b/pkg/core/resource/apis/system/v1alpha1/secret_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const SecretKind = "Secret"
+const SecretKind coremodel.ResourceKind = "Secret"
+
+func init() {
+       coremodel.RegisterResourceKind(SecretKind)
+}
 
 type SecretResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type SecretResourceList struct {
        Items           []SecretResource `json:"items"`
 }
 
-func (r *SecretResource) GetKind() string {
-       return r.Kind
+func (r *SecretResource) ResourceKind() coremodel.ResourceKind {
+       return SecretKind
 }
 
-func (r *SecretResource) GetMesh() string {
+func (r *SecretResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *SecretResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *SecretResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *SecretResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *SecretResource) GetMeta() metav1.ObjectMeta {
+func (r *SecretResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *SecretResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *SecretResource) GetSpec() coremodel.ResourceSpec {
+func (r *SecretResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *SecretResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*systemproto.Secret); ok {
-               r.Spec = spec
-               return nil
+func NewSecretResource(name string, mesh string, apiVersion string) 
*SecretResource {
+       return &SecretResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(SecretKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/system/v1alpha1/zone_types.go 
b/pkg/core/resource/apis/system/v1alpha1/zone_types.go
index 0f4aac30..d57d38f9 100644
--- a/pkg/core/resource/apis/system/v1alpha1/zone_types.go
+++ b/pkg/core/resource/apis/system/v1alpha1/zone_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const ZoneKind = "Zone"
+const ZoneKind coremodel.ResourceKind = "Zone"
+
+func init() {
+       coremodel.RegisterResourceKind(ZoneKind)
+}
 
 type ZoneResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ZoneResourceList struct {
        Items           []ZoneResource `json:"items"`
 }
 
-func (r *ZoneResource) GetKind() string {
-       return r.Kind
+func (r *ZoneResource) ResourceKind() coremodel.ResourceKind {
+       return ZoneKind
 }
 
-func (r *ZoneResource) GetMesh() string {
+func (r *ZoneResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ZoneResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ZoneResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ZoneResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ZoneResource) GetMeta() metav1.ObjectMeta {
+func (r *ZoneResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ZoneResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ZoneResource) GetSpec() coremodel.ResourceSpec {
+func (r *ZoneResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ZoneResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*systemproto.Zone); ok {
-               r.Spec = spec
-               return nil
+func NewZoneResource(name string, mesh string, apiVersion string) 
*ZoneResource {
+       return &ZoneResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ZoneKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go 
b/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go
index d479206d..6b21872a 100644
--- a/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go
+++ b/pkg/core/resource/apis/system/v1alpha1/zoneinsight_types.go
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// Generated by tools/resource-gen
+// Generated by tools/resourcegen
 // Run "make generate" to update this file.
 
 // nolint:whitespace
@@ -30,7 +30,11 @@ import (
 // +kubebuilder:object:root=true
 // +kubebuilder:resource:categories=dubbo,scope=Cluster
 
-const ZoneInsightKind = "ZoneInsight"
+const ZoneInsightKind coremodel.ResourceKind = "ZoneInsight"
+
+func init() {
+       coremodel.RegisterResourceKind(ZoneInsightKind)
+}
 
 type ZoneInsightResource struct {
        metav1.TypeMeta   `json:",inline"`
@@ -60,38 +64,36 @@ type ZoneInsightResourceList struct {
        Items           []ZoneInsightResource `json:"items"`
 }
 
-func (r *ZoneInsightResource) GetKind() string {
-       return r.Kind
+func (r *ZoneInsightResource) ResourceKind() coremodel.ResourceKind {
+       return ZoneInsightKind
 }
 
-func (r *ZoneInsightResource) GetMesh() string {
+func (r *ZoneInsightResource) MeshName() string {
        return r.Mesh
 }
 
-func (r *ZoneInsightResource) SetMesh(mesh string) {
-       r.Mesh = mesh
-}
-
-func (r *ZoneInsightResource) GetResourceKey() string {
-       return coremodel.BuildResourceKey(r.Mesh, r.Kind, r.Name)
+func (r *ZoneInsightResource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
 }
 
-func (r *ZoneInsightResource) GetMeta() metav1.ObjectMeta {
+func (r *ZoneInsightResource) ResourceMeta() metav1.ObjectMeta {
        return r.ObjectMeta
 }
 
-func (r *ZoneInsightResource) SetMeta(m metav1.ObjectMeta) {
-       r.ObjectMeta = m
-}
-
-func (r *ZoneInsightResource) GetSpec() coremodel.ResourceSpec {
+func (r *ZoneInsightResource) ResourceSpec() coremodel.ResourceSpec {
        return r.Spec
 }
 
-func (r *ZoneInsightResource) SetSpec(rs coremodel.ResourceSpec) error {
-       if spec, ok := rs.(*systemproto.ZoneInsight); ok {
-               r.Spec = spec
-               return nil
+func NewZoneInsightResource(name string, mesh string, apiVersion string) 
*ZoneInsightResource {
+       return &ZoneInsightResource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string(ZoneInsightKind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
        }
-       return coremodel.ErrorInvalidItemType(r.Spec, rs)
 }
diff --git a/pkg/core/resource/model/page.go b/pkg/core/resource/model/page.go
new file mode 100644
index 00000000..f91ad797
--- /dev/null
+++ b/pkg/core/resource/model/page.go
@@ -0,0 +1,15 @@
+package model
+
+type PageQuery struct {
+       PageSize    uint32
+       CurrentPage uint32
+       Page        bool
+}
+
+type Pagination struct {
+       PageSize    uint32
+       CurrentPage uint32
+       Total       uint32
+       Page        bool
+       NextOffset  string
+}
diff --git a/pkg/core/resource/model/registry.go 
b/pkg/core/resource/model/registry.go
new file mode 100644
index 00000000..8ed401c2
--- /dev/null
+++ b/pkg/core/resource/model/registry.go
@@ -0,0 +1,48 @@
+package model
+
+import ds "github.com/duke-git/lancet/v2/datastructure/set"
+
+var global = newRegistry()
+
+func ResourceKindRegistry() Registry {
+       return global
+}
+
+func RegisterResourceKind(kind ResourceKind) {
+       global.Register(kind)
+}
+
+type Registry interface {
+       // AllResourceKinds returns all registered resource kinds
+       AllResourceKinds() []ResourceKind
+}
+
+type RegistryMutator interface {
+       // Register registers a resource kind, if a resource kind has been 
registered before, it will be ignored
+       Register(kind ResourceKind)
+}
+
+type MutableRegistry interface {
+       Registry
+       RegistryMutator
+}
+
+var _ MutableRegistry = &resourceKindRegistry{}
+
+func newRegistry() MutableRegistry {
+       return &resourceKindRegistry{
+               kinds: ds.New[ResourceKind](),
+       }
+}
+
+type resourceKindRegistry struct {
+       kinds ds.Set[ResourceKind]
+}
+
+func (r *resourceKindRegistry) AllResourceKinds() []ResourceKind {
+       return r.kinds.ToSlice()
+}
+
+func (r *resourceKindRegistry) Register(kind ResourceKind) {
+       r.kinds.Add(kind)
+}
diff --git a/pkg/core/resource/model/resource.go 
b/pkg/core/resource/model/resource.go
index 2398e7c0..8b47d7cd 100644
--- a/pkg/core/resource/model/resource.go
+++ b/pkg/core/resource/model/resource.go
@@ -43,41 +43,33 @@ const (
        ExtensionsNodeNameKey              = "nodeName"
 )
 
-
-
 type ResourceSpec interface{}
 
-type Resource interface {
-       // GetKind returns the resource type, e.g. Application, Service etc.
-       GetKind() string
-       GetMesh()  string
-       GetResourceKey() string
-       GetMeta() metav1.ObjectMeta
-       SetMeta(metav1.ObjectMeta)
-       GetSpec() ResourceSpec
-       SetSpec(ResourceSpec) error
-}
+// ResourceKind defines the resource type
+type ResourceKind string
 
-// BuildResourceKey build a unique identifier for a resource, usually is 
`mesh/kind/name`
-func BuildResourceKey(mesh string, kind string, name string) string {
-       return mesh + separator +  kind + separator + name;
+func (rk ResourceKind) ToString() string {
+       return string(rk)
 }
 
-type PageQuery struct {
-       PageSize    uint32
-       CurrentPage uint32
-       Page        bool
+type Resource interface {
+       // ResourceKind returns the resource type, e.g. Application, Service 
etc.
+       ResourceKind() ResourceKind
+       // ResourceKey returns the unique resource key
+       ResourceKey() string
+       // MeshName returns the mesh which the resource belongs to
+       MeshName() string
+       // ResourceMeta returns the resource metadata
+       ResourceMeta() metav1.ObjectMeta
+       // ResourceSpec returns the resource spec
+       ResourceSpec() ResourceSpec
 }
 
-type Pagination struct {
-       PageSize    uint32
-       CurrentPage uint32
-       Total       uint32
-       Page        bool
-       NextOffset  string
+// BuildResourceKey build a unique identifier for a resource, usually is 
`mesh/kind/name`
+func BuildResourceKey(mesh string, name string) string {
+       return mesh + separator + name
 }
 
 func ErrorInvalidItemType(expected, actual interface{}) error {
        return fmt.Errorf("invalid argument type: expected=%q got=%q", 
reflect.TypeOf(expected), reflect.TypeOf(actual))
 }
-
diff --git a/pkg/core/runtime/component.go b/pkg/core/runtime/component.go
index a727d66e..29f3ece3 100644
--- a/pkg/core/runtime/component.go
+++ b/pkg/core/runtime/component.go
@@ -22,31 +22,33 @@ type ComponentType = string
 const (
        Console           ComponentType = "console"
        ResourceManager   ComponentType = "resource manager"
-       ResourceStore   ComponentType = "resource store"
+       ResourceStore     ComponentType = "resource store"
        ResourceEngine    ComponentType = "resource engine"
        ResourceDiscovery ComponentType = "resource discovery"
 )
 
 var CoreComponentTypes = []ComponentType{Console, ResourceManager, 
ResourceStore, ResourceEngine, ResourceDiscovery}
 
-type ComponentSubType = string
-
-const DefaultComponentSubType = "default"
+type Lifecycle interface {
+       // Init initializes the component
+       Init(ctx BuilderContext) error
+       // Start blocks until the channel is closed or an error occurs.
+       // The component will stop running when the channel is closed.
+       Start(Runtime, <-chan struct{}) error
+}
 
-// Component defines a process that will be run in the application
-// Component should be designed in such a way that it can be stopped by stop 
channel and started again (for example when instance is reelected for a leader).
-type Component interface {
+type Attribute interface {
        // Type returns the type of the component
        Type() ComponentType
-       // SubType returns the subtype of the component
-       SubType()  ComponentSubType
        // Order indicates the order of the component during bootstrap, the 
bigger will be started first
        Order() int
-       // Init initializes the component
-       Init(ctx BuilderContext) error
-       // Start blocks until the channel is closed or an error occurs.
-       // The component will stop running when the channel is closed.
-       Start(Runtime ,<-chan struct{}) error
+}
+
+// Component defines a process that will be run in the application
+// Component should be designed in such a way that it can be stopped by stop 
channel
+type Component interface {
+       Attribute
+       Lifecycle
 }
 
 // GracefulComponent is a component that supports waiting until it's finished.
@@ -62,11 +64,8 @@ type GracefulComponent interface {
 
 type ComponentManager interface {
        // Add adds a component to the manager.
-       Add(... Component)
+       Add(...Component)
 
        // Start starts all components.
-       Start( <-chan struct{}) error
+       Start(<-chan struct{}) error
 }
-
-
-
diff --git a/pkg/core/runtime/registry.go b/pkg/core/runtime/registry.go
index a1a36085..28e2196f 100644
--- a/pkg/core/runtime/registry.go
+++ b/pkg/core/runtime/registry.go
@@ -19,7 +19,6 @@ package runtime
 
 import (
        "github.com/pkg/errors"
-       "golang.org/x/exp/slices"
 )
 
 var global = NewRegistry()
@@ -35,12 +34,12 @@ func RegisterComponent(component Component) {
 }
 
 type Registry interface {
-       Get(typ ComponentType, subType ComponentSubType) (Component, error)
-       Console(subType ComponentSubType) (Component, error)
-       ResourceStore(subType ComponentSubType) (Component, error)
-       ResourceManager(subType ComponentSubType) (Component, error)
-       ResourceDiscovery(subType ComponentSubType) (Component, error)
-       ResourceEngine(subType ComponentSubType)         (Component, error)
+       Get(typ ComponentType) (Component, error)
+       Console() (Component, error)
+       ResourceStore() (Component, error)
+       ResourceManager() (Component, error)
+       ResourceDiscovery() (Component, error)
+       ResourceEngine() (Component, error)
 }
 
 type RegistryMutator interface {
@@ -54,71 +53,57 @@ type MutableRegistry interface {
 
 func NewRegistry() MutableRegistry {
        return &componentRegistry{
-               directory: make(map[ComponentType][]Component),
+               directory: make(map[ComponentType]Component),
        }
 }
 
 var _ MutableRegistry = &componentRegistry{}
 
 type componentRegistry struct {
-       directory map[ComponentType][]Component
+       directory map[ComponentType]Component
 }
 
-func (r *componentRegistry) Console(subType ComponentSubType) (Component, 
error) {
-       return r.Get(Console, subType)
+func (r *componentRegistry) Console() (Component, error) {
+       return r.Get(Console)
 }
 
-func (r *componentRegistry) ResourceManager(subType ComponentSubType) 
(Component, error) {
-       return r.Get(ResourceManager, subType)
+func (r *componentRegistry) ResourceManager() (Component, error) {
+       return r.Get(ResourceManager)
 }
 
-func (r *componentRegistry) ResourceStore(subType ComponentSubType) 
(Component, error) {
-       return r.Get(ResourceStore, subType)
+func (r *componentRegistry) ResourceStore() (Component, error) {
+       return r.Get(ResourceStore)
 }
 
-func (r *componentRegistry) ResourceDiscovery(subType ComponentSubType) 
(Component, error) {
-       return r.Get(ResourceDiscovery, subType)
+func (r *componentRegistry) ResourceDiscovery() (Component, error) {
+       return r.Get(ResourceDiscovery)
 }
 
-func (r *componentRegistry) ResourceEngine(subType ComponentSubType) 
(Component, error) {
-       return r.Get(ResourceEngine, subType)
+func (r *componentRegistry) ResourceEngine() (Component, error) {
+       return r.Get(ResourceEngine)
 }
 
 func (r *componentRegistry) Register(component Component) error {
-       components, ok := r.directory[component.Type()]
-       if !ok {
-               // if already registered
-               if slices.ContainsFunc(components, func(c Component) bool {
-                       return c.SubType() == component.SubType()
-               }) {
-                       return 
componentAlreadyRegisteredError(component.Type(), component.SubType())
-               }
-               // if not registered
-               r.directory[component.Type()] = append(components, component)
-               return nil
+       _, ok := r.directory[component.Type()]
+       if ok {
+               return componentAlreadyRegisteredError(component.Type())
        }
-       r.directory[component.SubType()] = []Component{component}
+       r.directory[component.Type()] = component
        return nil
 }
 
-func (r *componentRegistry) Get(typ ComponentType, subType ComponentSubType) 
(Component, error) {
-       components, ok := r.directory[typ]
+func (r *componentRegistry) Get(typ ComponentType) (Component, error) {
+       component, ok := r.directory[typ]
        if !ok {
-               return nil, noSuchComponentError(typ, subType)
-       }
-       index := slices.IndexFunc(components, func(component Component) bool {
-               return component.Type() == typ && component.SubType() == subType
-       })
-       if index == -1 {
-               return nil, noSuchComponentError(typ, subType)
+               return nil, noSuchComponentError(typ)
        }
-       return components[index], nil
+       return component, nil
 }
 
-func noSuchComponentError(typ ComponentType, subType ComponentSubType) error {
-       return errors.Errorf("there is no available component registered with 
type %q and subtype %q", typ, subType)
+func noSuchComponentError(typ ComponentType) error {
+       return errors.Errorf("there is no available component registered with 
type %q", typ)
 }
 
-func componentAlreadyRegisteredError(typ ComponentType, subType 
ComponentSubType) error {
-       return errors.Errorf("component %q with subType %q has already been 
registered", typ, subType)
+func componentAlreadyRegisteredError(typ ComponentType) error {
+       return errors.Errorf("component %q has already been registered", typ)
 }
diff --git a/pkg/core/store/component.go b/pkg/core/store/component.go
index d574ec03..7bbfdff1 100644
--- a/pkg/core/store/component.go
+++ b/pkg/core/store/component.go
@@ -1,40 +1,91 @@
 package store
 
 import (
+       "fmt"
        "math"
 
+       coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model"
        "github.com/apache/dubbo-admin/pkg/core/runtime"
 )
 
+type Router interface {
+       ResourceRoute(coremodel.Resource) (ResourceStore, error)
+       ResourceKindRoute(k coremodel.ResourceKind) (ResourceStore, error)
+}
+
+// The Component interface is composed of both functional interfaces and 
lifecycle interfaces
 type Component interface {
        runtime.Component
-       ResourceStore() ResourceStore
+       Router
 }
 
-var _ Component = &BaseResourceStoreComponent{}
+var _ Component = &storeComponent{}
 
-type BaseResourceStoreComponent struct{}
+// storeComponent combine the stores and route Resource a request to an 
appropriate store
+type storeComponent struct {
+       // stores every resource corresponds to a ResourceStore
+       stores map[coremodel.ResourceKind]ManagedResourceStore
+}
 
-func (b BaseResourceStoreComponent) Type() runtime.ComponentType {
+func (sc *storeComponent) Type() runtime.ComponentType {
        return runtime.ResourceStore
 }
 
-func (b BaseResourceStoreComponent) SubType() runtime.ComponentSubType {
-       panic("SubType() must be implemented by concrete 
ResourceStoreComponent")
+func (sc *storeComponent) Order() int {
+       return math.MaxInt
 }
 
-func (b BaseResourceStoreComponent) Order() int {
-       return math.MaxInt
+func (sc *storeComponent) Init(ctx runtime.BuilderContext) error {
+       // 1. retrieve store config and choose the corresponding store factory
+       cfg := ctx.Config().Store
+       factory, err := FactoryRegistry().GetStoreFactory(cfg.Type)
+       if err != nil {
+               return err
+       }
+       // 2. create store for each resource kind
+       for _, kind := range 
coremodel.ResourceKindRegistry().AllResourceKinds() {
+               store, err := factory.New(kind, cfg)
+               if err != nil {
+                       return err
+               }
+               sc.stores[kind] = store
+               if err = store.Init(ctx); err != nil {
+                       return err
+               }
+       }
+       // 3. add indexers for each kind of store
+       for kind, store := range sc.stores {
+               indexers := IndexersRegistry().Indexers(kind)
+               if indexers == nil {
+                       continue
+               }
+               if err := store.AddIndexers(indexers); err != nil {
+                       return err
+               }
+       }
+       return nil
 }
 
-func (b BaseResourceStoreComponent) Init(_ runtime.BuilderContext) error {
-       panic("Init() must be implemented by concrete ResourceStoreComponent")
+func (sc *storeComponent) Start(rt runtime.Runtime, ch <-chan struct{}) error {
+       for _, store := range sc.stores {
+               if err := store.Start(rt, ch); err != nil {
+                       return err
+               }
+       }
+       return nil
 }
 
-func (b BaseResourceStoreComponent) Start(runtime.Runtime, <-chan struct{}) 
error {
-       panic("Start() must be implemented by concrete ResourceStoreComponent")
+func (sc *storeComponent) ResourceRoute(r coremodel.Resource) (ResourceStore, 
error) {
+       if store, exists := sc.stores[r.ResourceKind()]; exists {
+               return store, nil
+       }
+       return nil, fmt.Errorf("%s is not supported by store yet", 
r.ResourceKind())
 }
 
-func (b BaseResourceStoreComponent) ResourceStore() ResourceStore {
-       panic("ResourceStore() must be implemented by concrete 
ResourceStoreComponent")
+func (sc *storeComponent) ResourceKindRoute(k coremodel.ResourceKind) 
(ResourceStore, error) {
+       if store, exists := sc.stores[k]; exists {
+               return store, nil
+       }
+       return nil, fmt.Errorf("%s is not supported by store yet", k)
+
 }
diff --git a/pkg/core/store/indexregistry.go b/pkg/core/store/indexregistry.go
new file mode 100644
index 00000000..4aeb65fe
--- /dev/null
+++ b/pkg/core/store/indexregistry.go
@@ -0,0 +1,60 @@
+package store
+
+import (
+       "github.com/apache/dubbo-admin/pkg/core/resource/model"
+       "k8s.io/client-go/tools/cache"
+)
+
+var indexRegistry = newIndexRegistry()
+
+func RegisterIndexers(rk model.ResourceKind, indexers cache.Indexers) {
+       indexRegistry.Register(rk, indexers)
+}
+
+func IndexersRegistry() IndexerRegistry {
+       return indexRegistry
+}
+
+type IndexerRegistry interface {
+       Indexers(model.ResourceKind) cache.Indexers
+}
+
+type IndexerRegistryMutator interface {
+       Register(model.ResourceKind, cache.Indexers)
+}
+
+type MutableIndexerRegistry interface {
+       IndexerRegistry
+       IndexerRegistryMutator
+}
+
+// ResourceIndexers defines the rIndexers belong to a specific model.Resource
+type ResourceIndexers struct {
+       rk       model.ResourceKind
+       indexers cache.Indexers
+}
+
+var _ IndexerRegistry = &indexerRegistry{}
+
+type indexerRegistry struct {
+       rIndexers []ResourceIndexers
+}
+
+func newIndexRegistry() MutableIndexerRegistry {
+       return &indexerRegistry{
+               rIndexers: make([]ResourceIndexers, 0),
+       }
+}
+
+func (i *indexerRegistry) Indexers(k model.ResourceKind) cache.Indexers {
+       for _, rIndexer := range i.rIndexers {
+               if rIndexer.rk == k {
+                       return rIndexer.indexers
+               }
+       }
+       return nil
+}
+
+func (i *indexerRegistry) Register(k model.ResourceKind, indexers 
cache.Indexers) {
+       i.rIndexers = append(i.rIndexers, ResourceIndexers{rk: k, indexers: 
indexers})
+}
diff --git a/pkg/core/store/options.go b/pkg/core/store/options.go
index 95648de4..684853d8 100644
--- a/pkg/core/store/options.go
+++ b/pkg/core/store/options.go
@@ -359,17 +359,17 @@ func GetConsistent() GetOptionsFunc {
 }
 
 func (l *GetOptions) Predicate(r coremodel.Resource) bool {
-       if l.Mesh != "" && r.GetMesh() != l.Mesh {
+       if l.Mesh != "" && r.Mesh() != l.Mesh {
                return false
        }
 
-       if l.Version != "" && r.GetMeta().ResourceVersion != l.Version {
+       if l.Version != "" && r.Meta().ResourceVersion != l.Version {
                return false
        }
 
        if len(l.Labels) > 0 {
                for k, v := range l.Labels {
-                       if r.GetMeta().Labels[k] != v {
+                       if r.Meta().Labels[k] != v {
                                return false
                        }
                }
@@ -481,24 +481,24 @@ func (l *ListOptions) HashCode() string {
 }
 
 func (l *ListOptions) Predicate(r coremodel.Resource) bool {
-       if l.Mesh != "" && r.GetMesh() != l.Mesh {
+       if l.Mesh != "" && r.Mesh() != l.Mesh {
                return false
        }
-       if l.NameEquals != "" && r.GetMeta().Name != l.NameEquals {
+       if l.NameEquals != "" && r.Meta().Name != l.NameEquals {
                return false
        }
 
-       if l.NameContains != "" && !strings.Contains(r.GetMeta().Name, 
l.NameContains) {
+       if l.NameContains != "" && !strings.Contains(r.Meta().Name, 
l.NameContains) {
                return false
        }
 
-       if l.ApplicationContains != "" && 
!strings.Contains(r.GetMeta().Labels[meshproto.ApplicationLabel], 
l.ApplicationContains) {
+       if l.ApplicationContains != "" && 
!strings.Contains(r.Meta().Labels[meshproto.ApplicationLabel], 
l.ApplicationContains) {
                return false
        }
 
        if len(l.Labels) > 0 {
                for k, v := range l.Labels {
-                       if r.GetMeta().Labels[k] != v {
+                       if r.Meta().Labels[k] != v {
                                return false
                        }
                }
diff --git a/pkg/core/store/store.go b/pkg/core/store/store.go
index 1c0c3665..dd3103cf 100644
--- a/pkg/core/store/store.go
+++ b/pkg/core/store/store.go
@@ -23,14 +23,24 @@ import (
        "reflect"
        "strings"
 
+       "github.com/apache/dubbo-admin/pkg/core/runtime"
        . "k8s.io/client-go/tools/cache"
 
        "github.com/apache/dubbo-admin/pkg/core/resource/model"
 )
 
+// ResourceStore defines the interface for the persistance of a resource
+// ResourceStore expanded the interface of cache.Indexer and cache.Store
 type ResourceStore interface {
-       Store
-       ListPageByKey(key string, pq model.PageQuery) (items []interface{}, p 
model.Pagination)
+       Indexer
+       ListPageByIndex(indexName string, indexValue interface{}, pq 
model.PageQuery) ([]interface{}, model.Pagination, error)
+}
+
+// ManagedResourceStore includes both functional interfaces and lifecycle 
interfaces
+// If there is a new type of ResourceStore, it should implement this interface
+type ManagedResourceStore interface {
+       runtime.Lifecycle
+       ResourceStore
 }
 
 type ResourceConflictError struct {
diff --git a/pkg/core/store/storeregistry.go b/pkg/core/store/storeregistry.go
new file mode 100644
index 00000000..7e5aaad6
--- /dev/null
+++ b/pkg/core/store/storeregistry.go
@@ -0,0 +1,63 @@
+package store
+
+import (
+       "fmt"
+
+       "github.com/apache/dubbo-admin/pkg/config/store"
+       "github.com/apache/dubbo-admin/pkg/core/resource/model"
+)
+
+var factoryRegistry = newStoreFactoryRegistry()
+
+func RegisterFactory(f Factory) {
+       factoryRegistry.Register(f)
+}
+
+func FactoryRegistry() Registry {
+       return factoryRegistry
+}
+
+// Factory is the interface for create a specific type of ManagedResourceStore
+type Factory interface {
+       // Support returns true if the factory supports the given type in config
+       Support(store.Type) bool
+       // New returns a new ManagedResourceStore for the model.ResourceKind 
using the given config
+       New(model.ResourceKind, *store.Config) (ManagedResourceStore, error)
+}
+
+type Registry interface {
+       GetStoreFactory(store.Type) (Factory, error)
+}
+
+type RegistryMutator interface {
+       // RegisterFactory registers a resource store type and a func to new it
+       Register(Factory)
+}
+type MutableRegistry interface {
+       Registry
+       RegistryMutator
+}
+
+var _ MutableRegistry = &storeFactoryRegistry{}
+
+type storeFactoryRegistry struct {
+       factories []Factory
+}
+
+func newStoreFactoryRegistry() MutableRegistry {
+       return &storeFactoryRegistry{
+               factories: make([]Factory, 0),
+       }
+}
+func (s *storeFactoryRegistry) GetStoreFactory(t store.Type) (Factory, error) {
+       for _, factory := range s.factories {
+               if factory.Support(t) {
+                       return factory, nil
+               }
+       }
+       return nil, fmt.Errorf("store type %s not supported", t)
+}
+
+func (s *storeFactoryRegistry) Register(factory Factory) {
+       s.factories = append(s.factories, factory)
+}
diff --git a/pkg/store/memory/memory.go b/pkg/store/memory/memory.go
index 96f356de..cff9dd2c 100644
--- a/pkg/store/memory/memory.go
+++ b/pkg/store/memory/memory.go
@@ -3,4 +3,3 @@ package memory
 import _ "k8s.io/client-go/tools/cache"
 
 // TODO implement memory resource store, refer to client-go cache.Store
-
diff --git a/tools/resourcegen/main.go b/tools/resourcegen/main.go
new file mode 100644
index 00000000..25915da3
--- /dev/null
+++ b/tools/resourcegen/main.go
@@ -0,0 +1,237 @@
+package main
+
+import (
+       "bytes"
+       "flag"
+       "fmt"
+       "go/format"
+       "log"
+       "os"
+       "path/filepath"
+       "sort"
+       "strings"
+       "text/template"
+
+       "google.golang.org/protobuf/reflect/protoreflect"
+       "google.golang.org/protobuf/reflect/protoregistry"
+
+       _ "github.com/apache/dubbo-admin/api/mesh/v1alpha1"
+       _ "github.com/apache/dubbo-admin/api/system/v1alpha1"
+
+       util "github.com/apache/dubbo-admin/tools/resourcegen/util"
+)
+
+// resourceTemplate for creating a Dubbo Resource.
+var resourceTemplate = template.Must(template.New("dubbo-resource").Parse(`
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Generated by tools/resourcegen
+// Run "make generate" to update this file.
+
+{{ $pkg := printf "%sproto" .Package }}
+{{ $tk := "` + "`" + `" }}
+
+// nolint:whitespace
+package v1alpha1
+
+import (
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+       {{ $pkg }} "github.com/apache/dubbo-admin/api/{{ .Package }}/v1alpha1"
+       coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model"
+)
+
+{{range .Resources}}
+
+// +kubebuilder:object:root=true
+{{- if .ScopeNamespace }}
+// +kubebuilder:resource:categories=dubbo,scope=Namespaced
+{{- else }}
+// +kubebuilder:resource:categories=dubbo,scope=Cluster
+{{- end}}
+{{- range .AdditionalPrinterColumns }}
+// +kubebuilder:printcolumn:{{ . }}
+{{- end}}
+
+const {{.ResourceType}}Kind coremodel.ResourceKind = "{{.ResourceType}}"
+
+func init() {
+       coremodel.RegisterResourceKind({{.ResourceType}}Kind)
+}
+
+type {{.ResourceType}}Resource struct {
+       metav1.TypeMeta   {{ $tk }}json:",inline"{{ $tk }}
+       metav1.ObjectMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }}
+
+    // Mesh is the name of the dubbo mesh this resource belongs to.
+       // It may be omitted for cluster-scoped resources.
+       //
+    // +kubebuilder:validation:Optional
+       Mesh string {{ $tk }}json:"mesh,omitempty"{{ $tk }}
+
+{{- if eq .ResourceType "DataplaneInsight" }}
+       // Status is the status the dubbo resource.
+    // +kubebuilder:validation:Optional
+       Status   *apiextensionsv1.JSON {{ $tk }}json:"status,omitempty"{{ $tk }}
+{{- else}}
+       // Spec is the specification of the Dubbo {{ .ProtoType }} resource.
+    // +kubebuilder:validation:Optional
+       Spec   *{{$pkg}}.{{.ResourceType}} {{ $tk }}json:"spec,omitempty"{{ $tk 
}}
+{{- end}}
+       // Status is the status of the Dubbo {{.ResourceType}} resource.
+       Status {{.ResourceType}}ResourceStatus {{ $tk 
}}json:"status,omitempty"{{ $tk }}
+}
+
+type {{.ResourceType}}ResourceStatus struct {
+       // define resource-specific status here
+}
+
+// +kubebuilder:object:root=true
+{{- if .ScopeNamespace }}
+// +kubebuilder:resource:scope=Cluster
+{{- else }}
+// +kubebuilder:resource:scope=Namespaced
+{{- end}}
+type {{.ResourceType}}ResourceList struct {
+       metav1.TypeMeta {{ $tk }}json:",inline"{{ $tk }}
+       metav1.ListMeta {{ $tk }}json:"metadata,omitempty"{{ $tk }}
+       Items           []{{.ResourceType}}Resource {{ $tk }}json:"items"{{ $tk 
}}
+}
+
+func (r *{{.ResourceType}}Resource) ResourceKind() coremodel.ResourceKind  {
+       return {{.ResourceType}}Kind
+}
+
+func (r *{{.ResourceType}}Resource) MeshName() string {
+       return r.Mesh
+}
+
+func (r *{{.ResourceType}}Resource) ResourceKey() string {
+       return coremodel.BuildResourceKey(r.Mesh, r.Name)
+}
+
+func (r *{{.ResourceType}}Resource) ResourceMeta() metav1.ObjectMeta {
+       return r.ObjectMeta
+}
+
+func (r *{{.ResourceType}}Resource) ResourceSpec() coremodel.ResourceSpec {
+       return r.Spec
+}
+
+func New{{.ResourceType}}Resource(name string, mesh string, apiVersion string) 
*{{.ResourceType}}Resource{
+       return &{{.ResourceType}}Resource{
+               TypeMeta: metav1.TypeMeta{
+                       Kind:       string({{.ResourceType}}Kind),
+                       APIVersion: apiVersion,
+               },
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:   name,
+                       Labels: map[string]string{},
+               },
+               Mesh: mesh,
+       }
+}
+
+{{- end }} {{/* Resources */}}
+`))
+
+// ProtoMessageFunc ...
+type ProtoMessageFunc func(protoreflect.MessageType) bool
+
+// OnDubboResourceMessage ...
+func OnDubboResourceMessage(pkg string, f ProtoMessageFunc) ProtoMessageFunc {
+       return func(m protoreflect.MessageType) bool {
+               r := util.DubboResourceForMessage(m.Descriptor())
+               if r == nil {
+                       return true
+               }
+
+               fullname := string(m.Descriptor().FullName())
+               if strings.Contains(fullname, "legacy") {
+                       log.Printf("Skipping message: %s", fullname)
+                       return true
+               }
+               if r.Package == pkg {
+                       return f(m)
+               }
+
+               return true
+       }
+}
+
+func main() {
+       var pkg string
+       var outputDir string
+
+       flag.StringVar(&pkg, "package", "", "the name of the package to 
generate: (mesh, system)")
+       flag.StringVar(&outputDir, "output", "", "the directory to write 
generated files")
+       flag.Parse()
+
+       switch pkg {
+       case "mesh", "system":
+       default:
+               log.Fatalf("package %s is not supported", pkg)
+       }
+
+       if err := os.MkdirAll(outputDir, 0755); err != nil {
+               log.Fatalf("failed to create output dir: %v", err)
+       }
+
+       var types []protoreflect.MessageType
+       protoregistry.GlobalTypes.RangeMessages(
+               OnDubboResourceMessage(pkg, func(m protoreflect.MessageType) 
bool {
+                       types = append(types, m)
+                       return true
+               }))
+
+       // Sort by name so the output is deterministic.
+       sort.Slice(types, func(i, j int) bool {
+               return types[i].Descriptor().FullName() < 
types[j].Descriptor().FullName()
+       })
+
+       var resources []util.ResourceInfo
+       for _, t := range types {
+               resourceInfo := util.ToResourceInfo(t.Descriptor())
+               resources = append(resources, resourceInfo)
+       }
+
+       for _, resource := range resources {
+               // 每次只传一个资源到模板中
+               var buf bytes.Buffer
+               if err := resourceTemplate.Execute(&buf, struct {
+                       Package   string
+                       Resources []util.ResourceInfo
+               }{
+                       Package:   pkg,
+                       Resources: []util.ResourceInfo{resource}, // 只放一个资源
+               }); err != nil {
+                       log.Fatalf("template error for %s: %s", 
resource.ResourceType, err)
+               }
+
+               out, err := format.Source(buf.Bytes())
+               if err != nil {
+                       log.Fatalf("format error for %s: %s", 
resource.ResourceType, err)
+               }
+
+               filename := filepath.Join(outputDir, fmt.Sprintf("%s_types.go", 
strings.ToLower(resource.ResourceType)))
+               if err := os.WriteFile(filename, out, 0644); err != nil {
+                       log.Fatalf("write file error for %s: %s", filename, err)
+               }
+
+               log.Printf("Generated: %s", filename)
+       }
+}
diff --git a/tools/resourcegen/util/util.go b/tools/resourcegen/util/util.go
new file mode 100644
index 00000000..397229ac
--- /dev/null
+++ b/tools/resourcegen/util/util.go
@@ -0,0 +1,135 @@
+package util
+
+import (
+       "fmt"
+
+       "golang.org/x/text/cases"
+       "golang.org/x/text/language"
+       "google.golang.org/protobuf/proto"
+       "google.golang.org/protobuf/reflect/protoreflect"
+
+       "github.com/apache/dubbo-admin/api/mesh"
+       coremodel "github.com/apache/dubbo-admin/pkg/core/resource/model"
+)
+
+// DubboResourceForMessage fetches the Dubbo resource option out of a message.
+func DubboResourceForMessage(desc protoreflect.MessageDescriptor) 
*mesh.DubboResourceOptions {
+       ext := proto.GetExtension(desc.Options(), mesh.E_Resource)
+       var resOption *mesh.DubboResourceOptions
+       if r, ok := ext.(*mesh.DubboResourceOptions); ok {
+               resOption = r
+       }
+
+       return resOption
+}
+
+// SelectorsForMessage finds all the top-level fields in the message are
+// repeated selectors. We want to generate convenience accessors for these.
+func SelectorsForMessage(m protoreflect.MessageDescriptor) []string {
+       var selectors []string
+       fields := m.Fields()
+
+       for i := 0; i < fields.Len(); i++ {
+               field := fields.Get(i)
+               m := field.Message()
+               if m != nil && m.FullName() == "dubbo.mesh.v1alpha1.Selector" {
+                       fieldName := string(field.Name())
+                       caser := cases.Title(language.English)
+                       selectors = append(selectors, caser.String(fieldName))
+               }
+       }
+
+       return selectors
+}
+
+type ResourceInfo struct {
+       ResourceName             string
+       ResourceType             string
+       ProtoType                string
+       Selectors                []string
+       SkipRegistration         bool
+       SkipKubernetesWrappers   bool
+       ScopeNamespace           bool
+       Global                   bool
+       DubboctlSingular         string
+       DubboctlPlural           string
+       WsReadOnly               bool
+       WsAdminOnly              bool
+       WsPath                   string
+       DdsDirection             string
+       AllowToInspect           bool
+       StorageVersion           bool
+       IsPolicy                 bool
+       SingularDisplayName      string
+       PluralDisplayName        string
+       IsExperimental           bool
+       AdditionalPrinterColumns []string
+       HasInsights              bool
+}
+
+func ToResourceInfo(desc protoreflect.MessageDescriptor) ResourceInfo {
+       r := DubboResourceForMessage(desc)
+
+       out := ResourceInfo{
+               ResourceType:             r.Type,
+               ResourceName:             r.Name,
+               ProtoType:                string(desc.Name()),
+               Selectors:                SelectorsForMessage(desc),
+               SkipRegistration:         r.SkipRegistration,
+               SkipKubernetesWrappers:   r.SkipKubernetesWrappers,
+               Global:                   r.Global,
+               ScopeNamespace:           r.ScopeNamespace,
+               AllowToInspect:           r.AllowToInspect,
+               StorageVersion:           r.StorageVersion,
+               SingularDisplayName:      coremodel.DisplayName(r.Type),
+               PluralDisplayName:        r.PluralDisplayName,
+               IsExperimental:           r.IsExperimental,
+               AdditionalPrinterColumns: r.AdditionalPrinterColumns,
+               HasInsights:              r.HasInsights,
+       }
+       if r.Ws != nil {
+               pluralResourceName := r.Ws.Plural
+               if pluralResourceName == "" {
+                       pluralResourceName = r.Ws.Name + "s"
+               }
+               out.WsReadOnly = r.Ws.ReadOnly
+               out.WsAdminOnly = r.Ws.AdminOnly
+               out.WsPath = pluralResourceName
+               if !r.Ws.ReadOnly {
+                       out.DubboctlSingular = r.Ws.Name
+                       out.DubboctlPlural = pluralResourceName
+                       // Keep the typo to preserve backward compatibility
+                       if out.DubboctlSingular == "health-check" {
+                               out.DubboctlSingular = "healthcheck"
+                               out.DubboctlPlural = "healthchecks"
+                       }
+               }
+       }
+       if out.PluralDisplayName == "" {
+               out.PluralDisplayName = 
coremodel.PluralType(coremodel.DisplayName(r.Type))
+       }
+       // Working around the fact we don't really differentiate policies from 
the rest of resources:
+       // Anything global can't be a policy as it need to be on a mesh. 
Anything with locked Ws config is something internal and therefore not a policy
+       out.IsPolicy = !out.SkipRegistration && !out.Global && !out.WsAdminOnly 
&& !out.WsReadOnly && out.ResourceType != "Dataplane" && out.ResourceType != 
"ExternalService"
+       switch {
+       case r.Dds == nil || (!r.Dds.SendToZone && !r.Dds.SendToGlobal):
+               out.DdsDirection = ""
+       case r.Dds.SendToGlobal && r.Dds.SendToZone:
+               out.DdsDirection = "model.ZoneToGlobalFlag | 
model.GlobalToAllButOriginalZoneFlag"
+       case r.Dds.SendToGlobal:
+               out.DdsDirection = "model.ZoneToGlobalFlag"
+       case r.Dds.SendToZone:
+               out.DdsDirection = "model.GlobalToAllZonesFlag"
+       }
+
+       if out.ResourceType == "MeshGateway" {
+               out.DdsDirection = "model.ZoneToGlobalFlag | 
model.GlobalToAllZonesFlag"
+       }
+
+       if p := desc.Parent(); p != nil {
+               if _, ok := p.(protoreflect.MessageDescriptor); ok {
+                       out.ProtoType = fmt.Sprintf("%s_%s", p.Name(), 
desc.Name())
+               }
+       }
+       return out
+}

Reply via email to