| /* |
| * 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. |
| */ |
| |
| package traditional |
| |
| import ( |
| "context" |
| "fmt" |
| "sync" |
| ) |
| |
| import ( |
| "dubbo.apache.org/dubbo-go/v3/common" |
| "dubbo.apache.org/dubbo-go/v3/config_center" |
| dubbo_identifier "dubbo.apache.org/dubbo-go/v3/metadata/identifier" |
| "dubbo.apache.org/dubbo-go/v3/metadata/report" |
| dubboRegistry "dubbo.apache.org/dubbo-go/v3/registry" |
| |
| "github.com/dubbogo/gost/encoding/yaml" |
| |
| "github.com/pkg/errors" |
| |
| "golang.org/x/exp/maps" |
| ) |
| |
| import ( |
| mesh_proto "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1" |
| "github.com/apache/dubbo-kubernetes/pkg/core/consts" |
| "github.com/apache/dubbo-kubernetes/pkg/core/governance" |
| "github.com/apache/dubbo-kubernetes/pkg/core/logger" |
| "github.com/apache/dubbo-kubernetes/pkg/core/reg_client" |
| "github.com/apache/dubbo-kubernetes/pkg/core/resources/apis/mesh" |
| core_model "github.com/apache/dubbo-kubernetes/pkg/core/resources/model" |
| "github.com/apache/dubbo-kubernetes/pkg/core/resources/store" |
| "github.com/apache/dubbo-kubernetes/pkg/events" |
| "github.com/apache/dubbo-kubernetes/pkg/plugins/util/ccache" |
| ) |
| |
| const ( |
| dubboGroup = "dubbo" |
| mappingGroup = "mapping" |
| dubboConfig = "config" |
| metadataGroup = "metadata" |
| cpGroup = "dubbo-cp" |
| pathSeparator = "/" |
| ) |
| |
| type traditionalStore struct { |
| configCenter config_center.DynamicConfiguration |
| metadataReport report.MetadataReport |
| registryCenter dubboRegistry.Registry |
| governance governance.GovernanceConfig |
| dCache *sync.Map |
| regClient reg_client.RegClient |
| eventWriter events.Emitter |
| mu sync.RWMutex |
| } |
| |
| func NewStore( |
| configCenter config_center.DynamicConfiguration, |
| metadataReport report.MetadataReport, |
| registryCenter dubboRegistry.Registry, |
| governance governance.GovernanceConfig, |
| dCache *sync.Map, |
| regClient reg_client.RegClient, |
| ) store.ResourceStore { |
| return &traditionalStore{ |
| configCenter: configCenter, |
| metadataReport: metadataReport, |
| registryCenter: registryCenter, |
| governance: governance, |
| dCache: dCache, |
| regClient: regClient, |
| } |
| } |
| |
| func (t *traditionalStore) SetEventWriter(writer events.Emitter) { |
| t.mu.Lock() |
| defer t.mu.Unlock() |
| t.eventWriter = writer |
| } |
| |
| func (t *traditionalStore) Create(_ context.Context, resource core_model.Resource, fs ...store.CreateOptionsFunc) error { |
| var err error |
| opts := store.NewCreateOptions(fs...) |
| |
| switch resource.Descriptor().Name { |
| case mesh.MappingType: |
| spec := resource.GetSpec() |
| mapping := spec.(*mesh_proto.Mapping) |
| appNames := mapping.ApplicationNames |
| serviceInterface := mapping.InterfaceName |
| for _, app := range appNames { |
| err = t.metadataReport.RegisterServiceAppMapping(serviceInterface, mappingGroup, app) |
| if err != nil { |
| return err |
| } |
| } |
| case mesh.MetaDataType: |
| spec := resource.GetSpec() |
| metadata := spec.(*mesh_proto.MetaData) |
| identifier := &dubbo_identifier.SubscriberMetadataIdentifier{ |
| Revision: metadata.GetRevision(), |
| BaseApplicationMetadataIdentifier: dubbo_identifier.BaseApplicationMetadataIdentifier{ |
| Application: metadata.GetApp(), |
| Group: dubboGroup, |
| }, |
| } |
| services := map[string]*common.ServiceInfo{} |
| // 把metadata赋值到services中 |
| for key, serviceInfo := range metadata.GetServices() { |
| services[key] = &common.ServiceInfo{ |
| Name: serviceInfo.GetName(), |
| Group: serviceInfo.GetGroup(), |
| Version: serviceInfo.GetVersion(), |
| Protocol: serviceInfo.GetProtocol(), |
| Path: serviceInfo.GetPath(), |
| Params: serviceInfo.GetParams(), |
| } |
| } |
| info := &common.MetadataInfo{ |
| App: metadata.GetApp(), |
| Revision: metadata.GetRevision(), |
| Services: services, |
| } |
| err = t.metadataReport.PublishAppMetadata(identifier, info) |
| if err != nil { |
| return err |
| } |
| case mesh.DataplaneType: |
| // Dataplane无法Create, 只能Get和List |
| case mesh.TagRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.TagRoute) |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| |
| err = t.governance.SetConfig(path, string(bytes)) |
| if err != nil { |
| return err |
| } |
| case mesh.ConditionRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.ConditionRoute) |
| |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| |
| err = t.governance.SetConfig(path, string(bytes)) |
| if err != nil { |
| return err |
| } |
| case mesh.DynamicConfigType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetOverridePath(id) |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| |
| err = t.governance.SetConfig(path, string(bytes)) |
| if err != nil { |
| return err |
| } |
| default: |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| |
| path := GenerateCpGroupPath(string(resource.Descriptor().Name), opts.Name) |
| // 使用RegClient |
| err = t.regClient.SetContent(path, bytes) |
| if err != nil { |
| return err |
| } |
| } |
| |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| CreationTime: opts.CreationTime, |
| ModificationTime: opts.CreationTime, |
| Labels: maps.Clone(opts.Labels), |
| }) |
| |
| if t.eventWriter != nil { |
| go func() { |
| t.eventWriter.Send(events.ResourceChangedEvent{ |
| Operation: events.Create, |
| Type: resource.Descriptor().Name, |
| Key: core_model.MetaToResourceKey(resource.GetMeta()), |
| }) |
| }() |
| } |
| return nil |
| } |
| |
| func (t *traditionalStore) Update(ctx context.Context, resource core_model.Resource, fs ...store.UpdateOptionsFunc) error { |
| opts := store.NewUpdateOptions(fs...) |
| |
| switch resource.Descriptor().Name { |
| case mesh.DataplaneType: |
| // Dataplane资源无法更新, 只能获取和删除 |
| case mesh.TagRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.TagRoute) |
| cfg, _ := t.governance.GetConfig(path) |
| if cfg == "" { |
| return fmt.Errorf("tag route %s not found", id) |
| } |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| err = t.governance.SetConfig(path, string(bytes)) |
| if err != nil { |
| return err |
| } |
| case mesh.ConditionRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.ConditionRoute) |
| cfg, err := t.governance.GetConfig(path) |
| if err != nil { |
| return err |
| } |
| if cfg == "" { |
| if cfg == "" { |
| return fmt.Errorf("no existing condition route for path: %s", path) |
| } |
| } |
| |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| err = t.governance.SetConfig(path, string(bytes)) |
| if err != nil { |
| return err |
| } |
| case mesh.DynamicConfigType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetOverridePath(id) |
| existConfig, err := t.governance.GetConfig(path) |
| if err != nil { |
| return err |
| } |
| override := &mesh_proto.DynamicConfig{} |
| err = yaml.UnmarshalYML([]byte(existConfig), override) |
| if err != nil { |
| return err |
| } |
| configs := make([]*mesh_proto.OverrideConfig, 0) |
| if len(override.Configs) > 0 { |
| for _, c := range override.Configs { |
| if consts.Configs.Contains(c.Type) { |
| configs = append(configs, c) |
| } |
| } |
| } |
| update := resource.GetSpec().(*mesh_proto.DynamicConfig) |
| configs = append(configs, update.Configs...) |
| override.Configs = configs |
| override.Enabled = update.Enabled |
| if b, err := yaml.MarshalYML(override); err != nil { |
| return err |
| } else { |
| err := t.governance.SetConfig(path, string(b)) |
| if err != nil { |
| return err |
| } |
| } |
| case mesh.MappingType: |
| spec := resource.GetSpec() |
| mapping := spec.(*mesh_proto.Mapping) |
| appNames := mapping.ApplicationNames |
| serviceInterface := mapping.InterfaceName |
| for _, app := range appNames { |
| path := getMappingPath(serviceInterface) |
| // 先使用regClient判断是否存在, 如果存在的话就先删除再更新 |
| bytes, err := t.regClient.GetContent(path) |
| if err != nil { |
| return err |
| } |
| if len(bytes) != 0 { |
| // 说明有内容, 需要先删除 |
| err := t.regClient.DeleteContent(path) |
| if err != nil { |
| return err |
| } |
| } |
| err = t.metadataReport.RegisterServiceAppMapping(serviceInterface, mappingGroup, app) |
| if err != nil { |
| return err |
| } |
| } |
| case mesh.MetaDataType: |
| spec := resource.GetSpec() |
| metadata := spec.(*mesh_proto.MetaData) |
| identifier := &dubbo_identifier.SubscriberMetadataIdentifier{ |
| Revision: metadata.GetRevision(), |
| BaseApplicationMetadataIdentifier: dubbo_identifier.BaseApplicationMetadataIdentifier{ |
| Application: metadata.GetApp(), |
| Group: dubboGroup, |
| }, |
| } |
| // 先判断identifier是否存在, 如果存在到话需要将其删除 |
| content, err := t.regClient.GetContent(getMetadataPath(metadata.GetApp(), metadata.GetRevision())) |
| if err != nil { |
| return err |
| } |
| if len(content) != 0 { |
| // 如果不为空, 先删除 |
| err := t.regClient.DeleteContent(getMetadataPath(metadata.GetApp(), metadata.GetRevision())) |
| if err != nil { |
| return err |
| } |
| } |
| services := map[string]*common.ServiceInfo{} |
| // 把metadata赋值到services中 |
| for key, serviceInfo := range metadata.GetServices() { |
| services[key] = &common.ServiceInfo{ |
| Name: serviceInfo.GetName(), |
| Group: serviceInfo.GetGroup(), |
| Version: serviceInfo.GetVersion(), |
| Protocol: serviceInfo.GetProtocol(), |
| Path: serviceInfo.GetPath(), |
| Params: serviceInfo.GetParams(), |
| } |
| } |
| info := &common.MetadataInfo{ |
| App: metadata.GetApp(), |
| Revision: metadata.GetRevision(), |
| Services: services, |
| } |
| err = t.metadataReport.PublishAppMetadata(identifier, info) |
| if err != nil { |
| return err |
| } |
| default: |
| bytes, err := core_model.ToYAML(resource.GetSpec()) |
| if err != nil { |
| return err |
| } |
| |
| path := GenerateCpGroupPath(string(resource.Descriptor().Name), opts.Name) |
| // 使用RegClient |
| err = t.regClient.SetContent(path, bytes) |
| if err != nil { |
| return err |
| } |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| ModificationTime: opts.ModificationTime, |
| Labels: maps.Clone(opts.Labels), |
| }) |
| |
| if t.eventWriter != nil { |
| go func() { |
| t.eventWriter.Send(events.ResourceChangedEvent{ |
| Operation: events.Update, |
| Type: resource.Descriptor().Name, |
| Key: core_model.MetaToResourceKey(resource.GetMeta()), |
| }) |
| }() |
| } |
| return nil |
| } |
| |
| func (t *traditionalStore) Delete(ctx context.Context, resource core_model.Resource, fs ...store.DeleteOptionsFunc) error { |
| opts := store.NewDeleteOptions(fs...) |
| |
| switch resource.Descriptor().Name { |
| case mesh.DataplaneType: |
| // 不支持删除 |
| case mesh.TagRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| key := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetOverridePath(key) |
| err := t.governance.DeleteConfig(path) |
| if err != nil { |
| return err |
| } |
| case mesh.ConditionRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| key := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(key, consts.ConditionRoute) |
| err := t.governance.DeleteConfig(path) |
| if err != nil { |
| return err |
| } |
| case mesh.DynamicConfigType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| key := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetOverridePath(key) |
| conf, err := t.governance.GetConfig(path) |
| if err != nil { |
| logger.Sugar().Error(err.Error()) |
| return err |
| } |
| if err := core_model.FromYAML([]byte(conf), resource.GetSpec()); err != nil { |
| return err |
| } |
| override := resource.GetSpec().(*mesh_proto.DynamicConfig) |
| if len(override.Configs) > 0 { |
| newConfigs := make([]*mesh_proto.OverrideConfig, 0) |
| for _, c := range override.Configs { |
| if consts.Configs.Contains(c.Type) { |
| newConfigs = append(newConfigs, c) |
| } |
| } |
| if len(newConfigs) == 0 { |
| err := t.governance.DeleteConfig(path) |
| if err != nil { |
| return err |
| } |
| } else { |
| override.Configs = newConfigs |
| if b, err := yaml.MarshalYML(override); err != nil { |
| return err |
| } else { |
| err := t.governance.SetConfig(path, string(b)) |
| if err != nil { |
| return err |
| } |
| } |
| } |
| } else { |
| err := t.governance.DeleteConfig(path) |
| if err != nil { |
| return err |
| } |
| } |
| case mesh.MappingType: |
| // 无法删除 |
| case mesh.MetaDataType: |
| // 无法删除 |
| default: |
| path := GenerateCpGroupPath(string(resource.Descriptor().Name), opts.Name) |
| err := t.regClient.DeleteContent(path) |
| if err != nil { |
| return err |
| } |
| } |
| |
| if t.eventWriter != nil { |
| go func() { |
| t.eventWriter.Send(events.ResourceChangedEvent{ |
| Operation: events.Delete, |
| Type: resource.Descriptor().Name, |
| Key: core_model.ResourceKey{ |
| Mesh: opts.Mesh, |
| Name: opts.Name, |
| }, |
| }) |
| }() |
| } |
| return nil |
| } |
| |
| func (c *traditionalStore) Get(_ context.Context, resource core_model.Resource, fs ...store.GetOptionsFunc) error { |
| opts := store.NewGetOptions(fs...) |
| |
| switch resource.Descriptor().Name { |
| case mesh.DataplaneType: |
| app := opts.Labels[mesh_proto.Application] |
| revision := opts.Labels[mesh_proto.Revision] |
| key := ccache.GetDataplaneKey(app, revision) |
| value, ok := c.dCache.Load(key) |
| if !ok { |
| return nil |
| } |
| r := value.(core_model.Resource) |
| resource.SetMeta(r.GetMeta()) |
| err := resource.SetSpec(r.GetSpec()) |
| if err != nil { |
| return err |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: key, |
| Mesh: opts.Mesh, |
| }) |
| case mesh.TagRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.TagRoute) |
| cfg, err := c.governance.GetConfig(path) |
| if err != nil { |
| return err |
| } |
| if cfg != "" { |
| if err := core_model.FromYAML([]byte(cfg), resource.GetSpec()); err != nil { |
| return errors.Wrap(err, "failed to convert json to spec") |
| } |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| case mesh.ConditionRouteType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetRoutePath(id, consts.ConditionRoute) |
| cfg, err := c.governance.GetConfig(path) |
| if err != nil { |
| return err |
| } |
| if cfg != "" { |
| if err := core_model.FromYAML([]byte(cfg), resource.GetSpec()); err != nil { |
| return errors.Wrap(err, "failed to convert json to spec") |
| } |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| case mesh.DynamicConfigType: |
| labels := opts.Labels |
| base := mesh_proto.Base{ |
| Application: labels[mesh_proto.Application], |
| Service: labels[mesh_proto.Service], |
| ID: labels[mesh_proto.ID], |
| ServiceVersion: labels[mesh_proto.ServiceVersion], |
| ServiceGroup: labels[mesh_proto.ServiceGroup], |
| } |
| id := mesh_proto.BuildServiceKey(base) |
| path := mesh_proto.GetOverridePath(id) |
| cfg, err := c.governance.GetConfig(path) |
| if err != nil { |
| return err |
| } |
| if cfg != "" { |
| if err := core_model.FromYAML([]byte(cfg), resource.GetSpec()); err != nil { |
| return errors.Wrap(err, "failed to convert json to spec") |
| } |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| case mesh.MappingType: |
| // Get通过Key获取, 不设置listener |
| key := opts.Name |
| set, err := c.metadataReport.GetServiceAppMapping(key, mappingGroup, nil) |
| if err != nil { |
| return err |
| } |
| meta := &resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| } |
| resource.SetMeta(meta) |
| mapping := resource.GetSpec().(*mesh_proto.Mapping) |
| mapping.Zone = "default" |
| mapping.InterfaceName = key |
| var items []string |
| for k := range set.Items { |
| items = append(items, fmt.Sprintf("%v", k)) |
| } |
| mapping.ApplicationNames = items |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| case mesh.MetaDataType: |
| labels := opts.Labels |
| revision := labels[mesh_proto.Revision] |
| app := labels[mesh_proto.Application] |
| if revision == "" { |
| children, err := c.regClient.GetChildren(getMetadataPath(app)) |
| if err != nil { |
| return err |
| } |
| revision = children[0] |
| } |
| id := dubbo_identifier.NewSubscriberMetadataIdentifier(app, revision) |
| appMetadata, err := c.metadataReport.GetAppMetadata(id) |
| if err != nil { |
| return err |
| } |
| metaData := resource.GetSpec().(*mesh_proto.MetaData) |
| metaData.App = appMetadata.App |
| metaData.Revision = appMetadata.Revision |
| service := map[string]*mesh_proto.ServiceInfo{} |
| for key, serviceInfo := range appMetadata.Services { |
| service[key] = &mesh_proto.ServiceInfo{ |
| Name: serviceInfo.Name, |
| Group: serviceInfo.Group, |
| Version: serviceInfo.Version, |
| Protocol: serviceInfo.Protocol, |
| Path: serviceInfo.Path, |
| Params: serviceInfo.Params, |
| } |
| } |
| metaData.Services = service |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| default: |
| path := GenerateCpGroupPath(string(resource.Descriptor().Name), opts.Name) |
| value, err := c.regClient.GetContent(path) |
| if err != nil { |
| return err |
| } |
| if err := core_model.FromYAML(value, resource.GetSpec()); err != nil { |
| return err |
| } |
| resource.SetMeta(&resourceMetaObject{ |
| Name: opts.Name, |
| Mesh: opts.Mesh, |
| }) |
| } |
| return nil |
| } |
| |
| func (c *traditionalStore) List(_ context.Context, resources core_model.ResourceList, fs ...store.ListOptionsFunc) error { |
| opts := store.NewListOptions(fs...) |
| |
| switch resources.GetItemType() { |
| case mesh.DataplaneType: |
| // iterator services key set |
| c.dCache.Range(func(key, value any) bool { |
| item := resources.NewItem() |
| r := value.(core_model.Resource) |
| item.SetMeta(&resourceMetaObject{ |
| Name: key.(string), |
| }) |
| err := item.SetSpec(r.GetSpec()) |
| if err != nil { |
| return false |
| } |
| if err := resources.AddItem(item); err != nil { |
| return false |
| } |
| return true |
| }) |
| case mesh.MappingType: |
| // 1. 首先获取到所有到key |
| keys, err := c.metadataReport.GetConfigKeysByGroup(mappingGroup) |
| if err != nil { |
| return err |
| } |
| for _, key := range keys.Values() { |
| key := key.(string) |
| // 通过key得到所有的mapping映射关系 |
| set, err := c.metadataReport.GetServiceAppMapping(key, mappingGroup, nil) |
| if err != nil { |
| return err |
| } |
| meta := &resourceMetaObject{ |
| Name: key, |
| } |
| item := resources.NewItem() |
| item.SetMeta(meta) |
| mapping := item.GetSpec().(*mesh_proto.Mapping) |
| mapping.Zone = "default" |
| mapping.InterfaceName = key |
| var items []string |
| for k := range set.Items { |
| items = append(items, fmt.Sprintf("%v", k)) |
| } |
| mapping.ApplicationNames = items |
| err = resources.AddItem(item) |
| if err != nil { |
| return err |
| } |
| } |
| case mesh.MetaDataType: |
| // 1. 获取到所有的key, key是application(应用名) |
| rootDir := getMetadataPath() |
| appNames, err := c.regClient.GetChildren(rootDir) |
| if err != nil { |
| return err |
| } |
| for _, app := range appNames { |
| // 2. 获取到该应用名下所有的revision |
| path := getMetadataPath(app) |
| revisions, err := c.regClient.GetChildren(path) |
| if err != nil { |
| return err |
| } |
| if revisions[0] == "provider" || |
| revisions[0] == "consumer" { |
| continue |
| } |
| for _, revision := range revisions { |
| id := dubbo_identifier.NewSubscriberMetadataIdentifier(app, revision) |
| appMetadata, err := c.metadataReport.GetAppMetadata(id) |
| if err != nil { |
| return err |
| } |
| item := resources.NewItem() |
| metaData := item.GetSpec().(*mesh_proto.MetaData) |
| metaData.App = appMetadata.App |
| metaData.Revision = appMetadata.Revision |
| service := map[string]*mesh_proto.ServiceInfo{} |
| for key, serviceInfo := range appMetadata.Services { |
| service[key] = &mesh_proto.ServiceInfo{ |
| Name: serviceInfo.Name, |
| Group: serviceInfo.Group, |
| Version: serviceInfo.Version, |
| Protocol: serviceInfo.Protocol, |
| Path: serviceInfo.Path, |
| Params: serviceInfo.Params, |
| } |
| } |
| metaData.Services = service |
| item.SetMeta(&resourceMetaObject{ |
| Name: app, |
| Version: revision, |
| }) |
| err = resources.AddItem(item) |
| if err != nil { |
| return err |
| } |
| } |
| } |
| |
| case mesh.DynamicConfigType: |
| // 不支持List |
| case mesh.TagRouteType: |
| // 不支持List |
| case mesh.ConditionRouteType: |
| // 不支持List |
| default: |
| rootDir := getDubboCpPath(string(resources.GetItemType())) |
| names, err := c.regClient.GetChildren(rootDir) |
| if err != nil { |
| return err |
| } |
| for _, name := range names { |
| path := getDubboCpPath(string(resources.GetItemType()), name) |
| bytes, err := c.regClient.GetContent(path) |
| if err != nil { |
| return err |
| } |
| item := resources.NewItem() |
| if err = core_model.FromYAML(bytes, item.GetSpec()); err != nil { |
| return err |
| } |
| item.SetMeta(&resourceMetaObject{ |
| Name: name, |
| Labels: maps.Clone(opts.Labels), |
| }) |
| err = resources.AddItem(item) |
| if err != nil { |
| return err |
| } |
| } |
| } |
| return nil |
| } |