github.com/polarismesh/polaris@v1.17.8/service/server.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package service 19 20 import ( 21 "context" 22 23 apiservice "github.com/polarismesh/specification/source/go/api/v1/service_manage" 24 "golang.org/x/sync/singleflight" 25 26 "github.com/polarismesh/polaris/cache" 27 cacheservice "github.com/polarismesh/polaris/cache/service" 28 "github.com/polarismesh/polaris/common/eventhub" 29 "github.com/polarismesh/polaris/common/model" 30 commontime "github.com/polarismesh/polaris/common/time" 31 "github.com/polarismesh/polaris/common/utils" 32 "github.com/polarismesh/polaris/namespace" 33 "github.com/polarismesh/polaris/plugin" 34 "github.com/polarismesh/polaris/service/batch" 35 "github.com/polarismesh/polaris/service/healthcheck" 36 "github.com/polarismesh/polaris/store" 37 ) 38 39 // Server 对接API层的server层,用以处理业务逻辑 40 type Server struct { 41 storage store.Store 42 43 namespaceSvr namespace.NamespaceOperateServer 44 45 caches *cache.CacheManager 46 bc *batch.Controller 47 48 healthServer *healthcheck.Server 49 50 cmdb plugin.CMDB 51 history plugin.History 52 ratelimit plugin.Ratelimit 53 54 l5service *l5service 55 56 createServiceSingle *singleflight.Group 57 58 hooks []ResourceHook 59 subCtxs []*eventhub.SubscribtionContext 60 61 instanceChains []InstanceChain 62 } 63 64 // HealthServer 健康检查Server 65 func (s *Server) HealthServer() *healthcheck.Server { 66 return s.healthServer 67 } 68 69 // Cache 返回Cache 70 func (s *Server) Cache() *cache.CacheManager { 71 return s.caches 72 } 73 74 // Namespace 返回NamespaceOperateServer 75 func (s *Server) Namespace() namespace.NamespaceOperateServer { 76 return s.namespaceSvr 77 } 78 79 // SetResourceHooks 设置资源操作的Hook 80 func (s *Server) SetResourceHooks(hooks ...ResourceHook) { 81 s.hooks = hooks 82 } 83 84 // AddInstanceChain . 85 func (s *Server) AddInstanceChain(chains ...InstanceChain) { 86 s.instanceChains = append(s.instanceChains, chains...) 87 } 88 89 // RecordHistory server对外提供history插件的简单封装 90 func (s *Server) RecordHistory(ctx context.Context, entry *model.RecordEntry) { 91 // 如果插件没有初始化,那么不记录history 92 if s.history == nil { 93 return 94 } 95 // 如果数据为空,则不需要打印了 96 if entry == nil { 97 return 98 } 99 100 fromClient, _ := ctx.Value(utils.ContextIsFromClient).(bool) 101 if fromClient { 102 return 103 } 104 // 调用插件记录history 105 s.history.Record(entry) 106 } 107 108 // RecordDiscoverStatis 打印服务发现统计 109 func (s *Server) RecordDiscoverStatis(service, discoverNamespace string) { 110 plugin.GetStatis().ReportDiscoverCall(service, discoverNamespace, commontime.CurrentMillisecond()) 111 } 112 113 // GetServiceInstanceRevision 获取服务实例的revision 114 func (s *Server) GetServiceInstanceRevision(serviceID string, instances []*model.Instance) (string, error) { 115 if revision := s.caches.Service().GetRevisionWorker().GetServiceInstanceRevision(serviceID); revision != "" { 116 return revision, nil 117 } 118 119 svc := s.Cache().Service().GetServiceByID(serviceID) 120 if svc == nil { 121 return "", model.ErrorNoService 122 } 123 124 data, err := cacheservice.ComputeRevision(svc.Revision, instances) 125 if err != nil { 126 return "", err 127 } 128 129 return data, nil 130 } 131 132 // 封装一下cmdb的GetLocation 133 func (s *Server) getLocation(host string) *model.Location { 134 if s.cmdb == nil { 135 return nil 136 } 137 138 location, err := s.cmdb.GetLocation(host) 139 if err != nil { 140 log.Errorf("[Server] get location(%s) err: %s", host, err.Error()) 141 return nil 142 } 143 return location 144 } 145 146 // 实例访问限流 147 func (s *Server) allowInstanceAccess(instanceID string) bool { 148 if s.ratelimit == nil { 149 return true 150 } 151 152 return s.ratelimit.Allow(plugin.InstanceRatelimit, instanceID) 153 } 154 155 func (s *Server) afterServiceResource(ctx context.Context, req *apiservice.Service, save *model.Service, 156 remove bool) error { 157 event := &ResourceEvent{ 158 ReqService: req, 159 Service: save, 160 IsRemove: remove, 161 } 162 163 for index := range s.hooks { 164 hook := s.hooks[index] 165 if err := hook.After(ctx, model.RService, event); err != nil { 166 return err 167 } 168 } 169 170 return nil 171 } 172 173 type InstanceChain interface { 174 // AfterUpdate . 175 AfterUpdate(ctx context.Context, instances ...*model.Instance) 176 }