github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/server/config.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"errors"
     7  	"path/filepath"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/google/uuid"
    12  	"github.com/volts-dev/utils"
    13  	"github.com/volts-dev/volts/broker"
    14  	"github.com/volts-dev/volts/config"
    15  	"github.com/volts-dev/volts/logger"
    16  	"github.com/volts-dev/volts/registry"
    17  	vrouter "github.com/volts-dev/volts/router"
    18  	"github.com/volts-dev/volts/transport"
    19  )
    20  
    21  type (
    22  	Option func(*Config)
    23  
    24  	Config struct {
    25  		config.Config `field:"-"`
    26  		Name          string `field:"-"` // config name/path in config file
    27  		PrefixName    string `field:"-"` // config prefix name
    28  		Uid           string `field:"-"` // 实例
    29  		//Tracer    trace.Tracer
    30  		Subscriber broker.ISubscriber   `field:"-"` // Subscribe to service name
    31  		Broker     broker.IBroker       `field:"-"`
    32  		Registry   registry.IRegistry   `field:"-"` // 实例
    33  		Transport  transport.ITransport `field:"-"` // 实例
    34  		Router     vrouter.IRouter      `field:"-"` // 实例 The router for requests
    35  		Logger     logger.ILogger       `field:"-"` // 实例
    36  		TLSConfig  *tls.Config          `field:"-"` // TLSConfig specifies tls.Config for secure serving
    37  
    38  		// Other options for implementations of the interface
    39  		// can be stored in a context
    40  		Context       context.Context             `field:"-"`
    41  		Metadata      map[string]string           `field:"-"`
    42  		RegisterCheck func(context.Context) error `field:"-"` // RegisterCheck runs a check function before registering the service
    43  
    44  		Address    string
    45  		Advertise  string
    46  		Version    string
    47  		AutoCreate bool // TODO 没必要 自动创建实例
    48  
    49  		// broker
    50  		BrokerType string
    51  		BrokerHost string
    52  
    53  		// Registry
    54  		RegistryType     string
    55  		RegistryHost     string
    56  		RegisterTTL      time.Duration `field:"register_ttl"` // The register expiry time
    57  		RegisterInterval time.Duration // The interval on which to register
    58  	}
    59  )
    60  
    61  var (
    62  	// App settings.
    63  	AppVer      string                             // 程序版本
    64  	AppName     string                             // 名称
    65  	AppUrl      string                             //
    66  	AppSubUrl   string                             //
    67  	AppFilePath string = utils.AppFilePath()       // 可执行程序文件绝对路径
    68  	AppPath     string = filepath.Dir(AppFilePath) // 可执行程序所在文件夹绝对路径
    69  	AppDir      string = filepath.Base(AppPath)    // 文件夹名称
    70  
    71  	DefaultAddress          = ":0"
    72  	DefaultName             = "default"
    73  	DefaultVersion          = "latest"
    74  	DefaultRegisterCheck    = func(context.Context) error { return nil }
    75  	DefaultRegisterInterval = time.Second * 30
    76  	DefaultRegisterTTL      = time.Second * 90
    77  	lastStreamResponseError = errors.New("EOS")
    78  )
    79  
    80  func newConfig(opts ...Option) *Config {
    81  	cfg := &Config{
    82  		PrefixName:       "server",
    83  		Name:             DefaultName,
    84  		Uid:              uuid.New().String(),
    85  		Logger:           log,
    86  		Metadata:         map[string]string{},
    87  		Address:          DefaultAddress,
    88  		RegisterInterval: DefaultRegisterInterval,
    89  		RegisterTTL:      DefaultRegisterTTL,
    90  		RegisterCheck:    DefaultRegisterCheck,
    91  		Version:          DefaultVersion,
    92  		AutoCreate:       true,
    93  	}
    94  	cfg.Init(opts...)
    95  	config.Register(cfg)
    96  
    97  	// 同过截取配置初始化对象
    98  	// 初始化 registry
    99  	if cfg.Registry == nil {
   100  		if reg := registry.Use(cfg.RegistryType, registry.WithConfigPrefixName(cfg.String()), registry.Addrs(cfg.RegistryHost)); reg != nil {
   101  			cfg.Init(WithRegistry(reg))
   102  		}
   103  	}
   104  
   105  	if cfg.Broker == nil {
   106  		if bk := broker.Use(cfg.BrokerType, broker.WithConfigPrefixName(cfg.String()), broker.Addrs(cfg.BrokerHost)); bk != nil {
   107  			cfg.Init(WithBroker(bk))
   108  		}
   109  	}
   110  
   111  	if cfg.Transport == nil {
   112  		cfg.Init(WithTransport(transport.Default()))
   113  	}
   114  	// if not special router use create new
   115  	if cfg.Router == nil {
   116  		cfg.Init(WithRouter(vrouter.New()))
   117  	}
   118  
   119  	return cfg
   120  }
   121  
   122  func (self *Config) String() string {
   123  	if len(self.PrefixName) > 0 {
   124  		return strings.Join([]string{self.PrefixName, self.Name}, ".")
   125  	}
   126  	return self.Name
   127  }
   128  
   129  func (self *Config) Init(opts ...Option) {
   130  	for _, opt := range opts {
   131  		opt(self)
   132  	}
   133  	/*
   134  
   135  	 */
   136  	if self.Debug {
   137  		self.Transport.Init(transport.Debug())
   138  		self.Router.Config().Init(vrouter.Debug())
   139  		if self.Registry == nil {
   140  			self.Registry.Config().Init(registry.Debug())
   141  		}
   142  	}
   143  }
   144  
   145  func (self *Config) Load() error {
   146  	return self.LoadToModel(self)
   147  
   148  }
   149  
   150  func (self *Config) Save(immed ...bool) error {
   151  	return self.SaveFromModel(self, immed...)
   152  }
   153  
   154  // under debug mode the port will keep at 35999
   155  func Debug() Option {
   156  	return func(cfg *Config) {
   157  		cfg.Debug = true
   158  		cfg.Router.Config().RequestPrinter = true
   159  		cfg.Router.Config().RouterTreePrinter = true
   160  		if cfg.Transport.String() == "Http Transport" {
   161  			cfg.Address = ":35999"
   162  		} else {
   163  			cfg.Address = ":45999"
   164  		}
   165  		//...
   166  	}
   167  }
   168  
   169  func Logger() logger.ILogger {
   170  	return log
   171  }
   172  
   173  // Server name
   174  func Name(name string) Option {
   175  	return func(cfg *Config) {
   176  		cfg.Unregister(cfg)
   177  		cfg.Name = name
   178  		cfg.Register(cfg)
   179  
   180  		prefixName := cfg.String()
   181  		if cfg.Broker != nil {
   182  			cfg.Broker.Init(broker.WithConfigPrefixName(prefixName))
   183  		}
   184  
   185  		if cfg.Transport != nil {
   186  			cfg.Transport.Init(transport.WithConfigPrefixName(prefixName))
   187  		}
   188  
   189  		if cfg.Router != nil {
   190  			cfg.Router.Config().Init(vrouter.WithConfigPrefixName(prefixName))
   191  		}
   192  	}
   193  }
   194  
   195  // 修改Config.json的路径
   196  func WithConfigPrefixName(prefixName string) Option {
   197  	return func(cfg *Config) {
   198  		cfg.Unregister(cfg)
   199  		cfg.PrefixName = prefixName
   200  		cfg.Register(cfg)
   201  
   202  		prefixName := cfg.String()
   203  		if cfg.Broker != nil {
   204  			cfg.Broker.Init(broker.WithConfigPrefixName(prefixName))
   205  		}
   206  
   207  		if cfg.Transport != nil {
   208  			cfg.Transport.Init(transport.WithConfigPrefixName(prefixName))
   209  		}
   210  
   211  		if cfg.Router != nil {
   212  			cfg.Router.Config().Init(vrouter.WithConfigPrefixName(prefixName))
   213  		}
   214  	}
   215  }
   216  
   217  func WithBroker(bk broker.IBroker) Option {
   218  	return func(cfg *Config) {
   219  		bk.Init(broker.WithConfigPrefixName(cfg.String()))
   220  		cfg.Broker = bk
   221  		cfg.BrokerType = bk.Config().Name
   222  		cfg.BrokerHost = bk.Address() // FIXME
   223  	}
   224  }
   225  
   226  // Registry used for discovery
   227  func WithRegistry(r registry.IRegistry) Option {
   228  	return func(cfg *Config) {
   229  		r.Init(registry.WithConfigPrefixName(cfg.String()))
   230  		cfg.Registry = r
   231  		cfg.RegistryType = r.Config().Name
   232  		///cfg.RegistryHost     = r.Config(). // FIXME
   233  
   234  		// Update Broker
   235  		if cfg.Broker != nil {
   236  			cfg.Broker.Init(broker.WithRegistry(r))
   237  		}
   238  
   239  		if cfg.Router != nil {
   240  			cfg.Router.Config().Init(vrouter.WithRegistry(r))
   241  		}
   242  	}
   243  }
   244  
   245  // not accept other router
   246  func WithRouter(router vrouter.IRouter) Option {
   247  	return func(cfg *Config) {
   248  		if _, ok := router.(*vrouter.TRouter); ok {
   249  			router.Config().Init(vrouter.WithConfigPrefixName(cfg.String()))
   250  			cfg.Router = router
   251  
   252  			// 避免执行顺序在WithRegistry后面
   253  			if cfg.Registry != nil {
   254  				cfg.Router.Config().Init(vrouter.WithRegistry(cfg.Registry))
   255  			}
   256  		}
   257  	}
   258  }
   259  
   260  // Transport mechanism for communication e.g http, rabbitmq, etc
   261  func WithTransport(t transport.ITransport) Option {
   262  	return func(cfg *Config) {
   263  		t.Init(transport.WithConfigPrefixName(cfg.String()))
   264  		cfg.Transport = t
   265  	}
   266  }
   267  
   268  // Address to bind to - host:port or :port
   269  func Address(addr string) Option {
   270  	return func(cfg *Config) {
   271  		cfg.Address = addr
   272  	}
   273  }
   274  
   275  // Context specifies a context for the service.
   276  // Can be used to signal shutdown of the service
   277  // Can be used for extra option values.
   278  func Context(ctx context.Context) Option {
   279  	return func(cfg *Config) {
   280  		cfg.Context = ctx
   281  	}
   282  }
   283  
   284  // RegisterCheck run func before registry service
   285  func RegisterCheck(fn func(context.Context) error) Option {
   286  	return func(cfg *Config) {
   287  		cfg.RegisterCheck = fn
   288  	}
   289  }
   290  
   291  // Register the service with a TTL
   292  func RegisterTTL(t time.Duration) Option {
   293  	return func(cfg *Config) {
   294  		cfg.RegisterTTL = t
   295  	}
   296  }
   297  
   298  // Register the service with at interval
   299  func RegisterInterval(t time.Duration) Option {
   300  	return func(cfg *Config) {
   301  		cfg.RegisterInterval = t
   302  	}
   303  }
   304  
   305  // TLSConfig specifies a *tls.Config
   306  func TLSConfig(t *tls.Config) Option {
   307  	return func(cfg *Config) {
   308  		// set the internal tls
   309  		cfg.TLSConfig = t
   310  
   311  		// set the default transport if one is not
   312  		// already set. Required for Init call below.
   313  		if cfg.Transport == nil {
   314  			cfg.Transport = transport.NewHTTPTransport()
   315  		}
   316  
   317  		// set the transport tls
   318  		cfg.Transport.Init(
   319  			transport.Secure(true),
   320  			transport.TLSConfig(t),
   321  		)
   322  	}
   323  }
   324  
   325  // 如果为False服务器不会自动创建默认必要组件实例,开发者自己配置
   326  func AutoCreate(open bool) Option {
   327  	return func(cfg *Config) {
   328  		cfg.AutoCreate = open
   329  	}
   330  }