github.com/polarismesh/polaris@v1.17.8/config/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 config
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  
    24  	apiconfig "github.com/polarismesh/specification/source/go/api/v1/config_manage"
    25  
    26  	"github.com/polarismesh/polaris/auth"
    27  	"github.com/polarismesh/polaris/cache"
    28  	cachetypes "github.com/polarismesh/polaris/cache/api"
    29  	"github.com/polarismesh/polaris/common/model"
    30  	"github.com/polarismesh/polaris/common/utils"
    31  	"github.com/polarismesh/polaris/namespace"
    32  	"github.com/polarismesh/polaris/plugin"
    33  	"github.com/polarismesh/polaris/store"
    34  )
    35  
    36  var _ ConfigCenterServer = (*Server)(nil)
    37  
    38  const (
    39  	// 文件内容限制为 2w 个字符
    40  	fileContentMaxLength = 20000
    41  )
    42  
    43  var (
    44  	server       ConfigCenterServer
    45  	originServer = &Server{}
    46  )
    47  
    48  var (
    49  	availableSearch = map[string]map[string]string{
    50  		"config_file": {
    51  			"namespace":   "namespace",
    52  			"group":       "group",
    53  			"name":        "name",
    54  			"offset":      "offset",
    55  			"limit":       "limit",
    56  			"order_type":  "order_type",
    57  			"order_field": "order_field",
    58  		},
    59  		"config_file_release": {
    60  			"namespace":    "namespace",
    61  			"group":        "group",
    62  			"file_name":    "file_name",
    63  			"fileName":     "file_name",
    64  			"name":         "release_name",
    65  			"release_name": "release_name",
    66  			"offset":       "offset",
    67  			"limit":        "limit",
    68  			"order_type":   "order_type",
    69  			"order_field":  "order_field",
    70  			"only_active":  "only_active",
    71  		},
    72  		"config_file_group": {
    73  			"namespace":   "namespace",
    74  			"group":       "name",
    75  			"name":        "name",
    76  			"business":    "business",
    77  			"department":  "department",
    78  			"offset":      "offset",
    79  			"limit":       "limit",
    80  			"order_type":  "order_type",
    81  			"order_field": "order_field",
    82  		},
    83  		"config_file_release_history": {
    84  			"namespace":   "namespace",
    85  			"group":       "group",
    86  			"name":        "file_name",
    87  			"offset":      "offset",
    88  			"limit":       "limit",
    89  			"endId":       "endId",
    90  			"end_id":      "endId",
    91  			"order_type":  "order_type",
    92  			"order_field": "order_field",
    93  		},
    94  	}
    95  )
    96  
    97  // Config 配置中心模块启动参数
    98  type Config struct {
    99  	Open             bool  `yaml:"open"`
   100  	ContentMaxLength int64 `yaml:"contentMaxLength"`
   101  }
   102  
   103  // Server 配置中心核心服务
   104  type Server struct {
   105  	cfg *Config
   106  
   107  	storage           store.Store
   108  	fileCache         cachetypes.ConfigFileCache
   109  	groupCache        cachetypes.ConfigGroupCache
   110  	caches            *cache.CacheManager
   111  	watchCenter       *watchCenter
   112  	connManager       *connManager
   113  	namespaceOperator namespace.NamespaceOperateServer
   114  	initialized       bool
   115  
   116  	history       plugin.History
   117  	cryptoManager plugin.CryptoManager
   118  	hooks         []ResourceHook
   119  
   120  	// chains
   121  	chains *ConfigChains
   122  
   123  	sequence int64
   124  }
   125  
   126  // Initialize 初始化配置中心模块
   127  func Initialize(ctx context.Context, config Config, s store.Store, cacheMgn *cache.CacheManager,
   128  	namespaceOperator namespace.NamespaceOperateServer, userMgn auth.UserServer, strategyMgn auth.StrategyServer) error {
   129  	if !config.Open {
   130  		originServer.initialized = true
   131  		return nil
   132  	}
   133  
   134  	if originServer.initialized {
   135  		return nil
   136  	}
   137  
   138  	err := originServer.initialize(ctx, config, s, namespaceOperator, cacheMgn)
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	server = newServerAuthAbility(originServer, userMgn, strategyMgn)
   144  	originServer.initialized = true
   145  	return nil
   146  }
   147  
   148  func (s *Server) initialize(ctx context.Context, config Config, ss store.Store,
   149  	namespaceOperator namespace.NamespaceOperateServer, cacheMgn *cache.CacheManager) error {
   150  
   151  	var err error
   152  
   153  	s.cfg = &config
   154  	if s.cfg.ContentMaxLength <= 0 {
   155  		s.cfg.ContentMaxLength = fileContentMaxLength
   156  	}
   157  	s.storage = ss
   158  	s.namespaceOperator = namespaceOperator
   159  	s.fileCache = cacheMgn.ConfigFile()
   160  	s.groupCache = cacheMgn.ConfigGroup()
   161  
   162  	s.watchCenter, err = NewWatchCenter()
   163  	if err != nil {
   164  		return err
   165  	}
   166  
   167  	// 初始化连接管理器
   168  	connMng := NewConfigConnManager(ctx, s.watchCenter)
   169  	s.connManager = connMng
   170  
   171  	// 获取History插件,注意:插件的配置在bootstrap已经设置好
   172  	s.history = plugin.GetHistory()
   173  	if s.history == nil {
   174  		log.Warnf("Not Found History Log Plugin")
   175  	}
   176  	// 获取Crypto插件
   177  	s.cryptoManager = plugin.GetCryptoManager()
   178  	if s.cryptoManager == nil {
   179  		log.Warnf("Not Found Crypto Plugin")
   180  	}
   181  
   182  	s.caches = cacheMgn
   183  	s.chains = newConfigChains(s, []ConfigFileChain{
   184  		&CryptoConfigFileChain{},
   185  		&ReleaseConfigFileChain{},
   186  	})
   187  
   188  	log.Infof("[Config][Server] startup config module success.")
   189  	return nil
   190  }
   191  
   192  // GetServer 获取已经初始化好的ConfigServer
   193  func GetServer() (ConfigCenterServer, error) {
   194  	if !originServer.initialized {
   195  		return nil, errors.New("config server has not done initialize")
   196  	}
   197  
   198  	return server, nil
   199  }
   200  
   201  func GetOriginServer() (*Server, error) {
   202  	if !originServer.initialized {
   203  		return nil, errors.New("config server has not done initialize")
   204  	}
   205  
   206  	return originServer, nil
   207  }
   208  
   209  // WatchCenter 获取监听事件中心
   210  func (s *Server) WatchCenter() *watchCenter {
   211  	return s.watchCenter
   212  }
   213  
   214  // Cache 获取配置中心缓存模块
   215  func (s *Server) Cache() cachetypes.ConfigFileCache {
   216  	return s.fileCache
   217  }
   218  
   219  // ConnManager 获取配置中心连接管理器
   220  func (s *Server) ConnManager() *connManager {
   221  	return s.connManager
   222  }
   223  
   224  // CryptoManager 获取加密管理
   225  func (s *Server) CryptoManager() plugin.CryptoManager {
   226  	return s.cryptoManager
   227  }
   228  
   229  // SetResourceHooks 设置资源钩子
   230  func (s *Server) SetResourceHooks(hooks ...ResourceHook) {
   231  	s.hooks = hooks
   232  }
   233  
   234  func (s *Server) afterConfigGroupResource(ctx context.Context, req *apiconfig.ConfigFileGroup) error {
   235  	event := &ResourceEvent{
   236  		ConfigGroup: req,
   237  	}
   238  
   239  	for _, hook := range s.hooks {
   240  		if err := hook.After(ctx, model.RConfigGroup, event); err != nil {
   241  			return err
   242  		}
   243  	}
   244  	return nil
   245  }
   246  
   247  // RecordHistory server对外提供history插件的简单封装
   248  func (s *Server) RecordHistory(ctx context.Context, entry *model.RecordEntry) {
   249  	// 如果插件没有初始化,那么不记录history
   250  	if s.history == nil {
   251  		return
   252  	}
   253  	// 如果数据为空,则不需要打印了
   254  	if entry == nil {
   255  		return
   256  	}
   257  
   258  	fromClient, _ := ctx.Value(utils.ContextIsFromClient).(bool)
   259  	if fromClient {
   260  		return
   261  	}
   262  	// 调用插件记录history
   263  	s.history.Record(entry)
   264  }
   265  
   266  func newConfigChains(svr *Server, chains []ConfigFileChain) *ConfigChains {
   267  	for i := range chains {
   268  		chains[i].Init(svr)
   269  	}
   270  	return &ConfigChains{chains: chains}
   271  }
   272  
   273  type ConfigChains struct {
   274  	chains []ConfigFileChain
   275  }
   276  
   277  // BeforeCreateFile
   278  func (cc *ConfigChains) BeforeCreateFile(ctx context.Context, file *model.ConfigFile) *apiconfig.ConfigResponse {
   279  	for i := range cc.chains {
   280  		if errResp := cc.chains[i].BeforeCreateFile(ctx, file); errResp != nil {
   281  			return errResp
   282  		}
   283  	}
   284  	return nil
   285  }
   286  
   287  // AfterGetFile
   288  func (cc *ConfigChains) AfterGetFile(ctx context.Context, file *model.ConfigFile) (*model.ConfigFile, error) {
   289  	file.OriginContent = file.Content
   290  	for i := range cc.chains {
   291  		_file, err := cc.chains[i].AfterGetFile(ctx, file)
   292  		if err != nil {
   293  			return nil, err
   294  		}
   295  		file = _file
   296  	}
   297  	return file, nil
   298  }
   299  
   300  // BeforeUpdateFile
   301  func (cc *ConfigChains) BeforeUpdateFile(ctx context.Context, file *model.ConfigFile) *apiconfig.ConfigResponse {
   302  	for i := range cc.chains {
   303  		if errResp := cc.chains[i].BeforeUpdateFile(ctx, file); errResp != nil {
   304  			return errResp
   305  		}
   306  	}
   307  	return nil
   308  }
   309  
   310  // AfterGetFileRelease
   311  func (cc *ConfigChains) AfterGetFileRelease(ctx context.Context,
   312  	release *model.ConfigFileRelease) (*model.ConfigFileRelease, error) {
   313  
   314  	for i := range cc.chains {
   315  		_release, err := cc.chains[i].AfterGetFileRelease(ctx, release)
   316  		if err != nil {
   317  			return nil, err
   318  		}
   319  		release = _release
   320  	}
   321  	return release, nil
   322  }
   323  
   324  // AfterGetFileHistory
   325  func (cc *ConfigChains) AfterGetFileHistory(ctx context.Context,
   326  	history *model.ConfigFileReleaseHistory) (*model.ConfigFileReleaseHistory, error) {
   327  	for i := range cc.chains {
   328  		_history, err := cc.chains[i].AfterGetFileHistory(ctx, history)
   329  		if err != nil {
   330  			return nil, err
   331  		}
   332  		history = _history
   333  	}
   334  	return history, nil
   335  }