Skip to content

Commit

Permalink
fix:服务列表支持服务可见性&修复服务可见性优先级判断
Browse files Browse the repository at this point in the history
  • Loading branch information
chuntaojun committed Nov 29, 2024
1 parent db26d9d commit 722ebbf
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
4 changes: 3 additions & 1 deletion cache/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,9 @@ type (
// GetRevisionWorker .
GetRevisionWorker() ServiceRevisionWorker
// GetVisibleServicesInOtherNamespace get same service in other namespace and it's visible
GetVisibleServicesInOtherNamespace(name string, namespace string) []*model.Service
// 如果 name == *,表示返回所有对 namespace 可见的服务
// 如果 name 是具体服务,表示返回对 name + namespace 设置了可见的服务
GetVisibleServicesInOtherNamespace(ctx context.Context, name string, namespace string) []*model.Service
}

// ServiceRevisionWorker
Expand Down
39 changes: 33 additions & 6 deletions cache/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,15 +637,15 @@ func (sc *serviceCache) updateCl5SidAndNames(service *model.Service) {
}

// GetVisibleServicesInOtherNamespace 查询是否存在别的命名空间下存在名称相同且可见的服务
func (sc *serviceCache) GetVisibleServicesInOtherNamespace(svcName, namespace string) []*model.Service {
func (sc *serviceCache) GetVisibleServicesInOtherNamespace(ctx context.Context, svcName, namespace string) []*model.Service {
ret := make(map[string]*model.Service)
// 根据服务级别的可见性进行查询, 先查询精确匹配
sc.exportServices.ReadRange(func(exportToNs string, services *utils.SyncMap[string, *model.Service]) {
if exportToNs != namespace && exportToNs != types.AllMatched {
return
}
services.ReadRange(func(_ string, svc *model.Service) {
if svc.Name == svcName && svc.Namespace != namespace {
if (svc.Name == svcName || utils.IsMatchAll(svcName)) && svc.Namespace != namespace {
ret[svc.ID] = svc
}
})
Expand All @@ -658,11 +658,38 @@ func (sc *serviceCache) GetVisibleServicesInOtherNamespace(svcName, namespace st
if !exactMatch && !allMatch {
return
}
svc := sc.GetServiceByName(svcName, exportNs)
if svc == nil {
return
if utils.IsMatchAll(svcName) {
// 如果是全匹配,那就看下这个命名空间下的所有服务
_, svcs := sc.ListServices(ctx, exportNs)
for i := range svcs {
if len(svcs[i].ExportTo) != 0 {
// 需要在额外判断下 svc 自己可见性设置
_, exactMatch := svcs[i].ExportTo[namespace]
_, allMatch := svcs[i].ExportTo[types.AllMatched]
if !exactMatch && !allMatch {
continue
}
}

ret[svcs[i].ID] = svcs[i]
}
} else {
svc := sc.GetServiceByName(svcName, exportNs)
if svc == nil {
return
}
// 可能 svc 有自己的可见性设置,此处优先级高于 namespace 的可见性设置
if len(svc.ExportTo) != 0 {
// 需要在额外判断下 svc 自己可见性设置
_, exactMatch := svc.ExportTo[namespace]
_, allMatch := svc.ExportTo[namespace]
if !exactMatch && !allMatch {
return
}
}

ret[svc.ID] = svc
}
ret[svc.ID] = svc
})

visibleServices := make([]*model.Service, 0, len(ret))
Expand Down
8 changes: 4 additions & 4 deletions cache/service/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ func Test_serviceCache_GetVisibleServicesInOtherNamespace(t *testing.T) {
})

_, _, _ = svcCache.setServices(serviceList)
visibles := svcCache.GetVisibleServicesInOtherNamespace("service-1", "ns-2")
visibles := svcCache.GetVisibleServicesInOtherNamespace(context.Background(), "service-1", "ns-2")
assert.Equal(t, 1, len(visibles))
assert.Equal(t, "ns-1", visibles[0].Namespace)
})
Expand Down Expand Up @@ -707,15 +707,15 @@ func Test_serviceCache_GetVisibleServicesInOtherNamespace(t *testing.T) {
},
})

visibles := svcCache.GetVisibleServicesInOtherNamespace("service-1", "ns-2")
visibles := svcCache.GetVisibleServicesInOtherNamespace(context.Background(), "service-1", "ns-2")
assert.Equal(t, 1, len(visibles))
assert.Equal(t, "ns-1", visibles[0].Namespace)

visibles = svcCache.GetVisibleServicesInOtherNamespace("service-1", "ns-3")
visibles = svcCache.GetVisibleServicesInOtherNamespace(context.Background(), "service-1", "ns-3")
assert.Equal(t, 1, len(visibles))
assert.Equal(t, "ns-1", visibles[0].Namespace)

visibles = svcCache.GetVisibleServicesInOtherNamespace("service-1", "ns-4")
visibles = svcCache.GetVisibleServicesInOtherNamespace(context.Background(), "service-1", "ns-4")
assert.Equal(t, 0, len(visibles))
})

Expand Down
29 changes: 23 additions & 6 deletions service/client_v1.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,23 @@ func (s *Server) GetServiceWithCache(ctx context.Context, req *apiservice.Servic

if req.GetNamespace().GetValue() != "" {
revision, svcs = s.Cache().Service().ListServices(ctx, req.GetNamespace().GetValue())
// 需要加上服务可见性处理
visibleSvcs := s.caches.Service().GetVisibleServicesInOtherNamespace(ctx, utils.MatchAll, req.GetNamespace().GetValue())
revisions := make([]string, 0, len(visibleSvcs)+1)
revisions = append(revisions, revision)
for i := range visibleSvcs {
revisions = append(revisions, visibleSvcs[i].Revision)
}
if rever, err := cachetypes.CompositeComputeRevision(revisions); err != nil {
// 如果计算失败,直接返回一个新的revision
revision = utils.NewUUID()
} else {
revision = rever
}
svcs = append(svcs, visibleSvcs...)
// 需要重新计算 revison
} else {
// 这里拉的是全部服务实例列表,如果客户端可以发起这个请求,应该是不需要
revision, svcs = s.Cache().Service().ListAllServices(ctx)
}
if revision == "" {
Expand Down Expand Up @@ -212,14 +228,14 @@ func (s *Server) ServiceInstancesCache(ctx context.Context, filter *apiservice.D
req *apiservice.Service) *apiservice.DiscoverResponse {

resp := createCommonDiscoverResponse(req, apiservice.DiscoverResponse_INSTANCE)
serviceName := req.GetName().GetValue()
namespaceName := req.GetNamespace().GetValue()
svcName := req.GetName().GetValue()
nsName := req.GetNamespace().GetValue()

// 数据源都来自Cache,这里拿到的service,已经是源服务
aliasFor, visibleServices := s.findVisibleServices(serviceName, namespaceName, req)
aliasFor, visibleServices := s.findVisibleServices(ctx, svcName, nsName, req)
if len(visibleServices) == 0 {
log.Infof("[Server][Service][Instance] not found name(%s) namespace(%s) service",
serviceName, namespaceName)
svcName, nsName)
return api.NewDiscoverInstanceResponse(apimodel.Code_NotFoundResource, req)
}

Expand Down Expand Up @@ -273,14 +289,15 @@ func (s *Server) ServiceInstancesCache(ctx context.Context, filter *apiservice.D
return resp
}

func (s *Server) findVisibleServices(serviceName, namespaceName string, req *apiservice.Service) (*model.Service, []*model.Service) {
func (s *Server) findVisibleServices(ctx context.Context, serviceName, namespaceName string,
req *apiservice.Service) (*model.Service, []*model.Service) {
visibleServices := make([]*model.Service, 0, 4)
// 数据源都来自Cache,这里拿到的service,已经是源服务
aliasFor := s.getServiceCache(serviceName, namespaceName)
if aliasFor != nil {
visibleServices = append(visibleServices, aliasFor)
}
ret := s.caches.Service().GetVisibleServicesInOtherNamespace(serviceName, namespaceName)
ret := s.caches.Service().GetVisibleServicesInOtherNamespace(ctx, serviceName, namespaceName)
if len(ret) > 0 {
visibleServices = append(visibleServices, ret...)
}
Expand Down
26 changes: 26 additions & 0 deletions service/client_v1_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Tencent is pleased to support the open source community by making Polaris available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* 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 service

import (
"testing"
)

func TestServer_GetServiceWithCache(t *testing.T) {
// TODO
}

0 comments on commit 722ebbf

Please sign in to comment.