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  }