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 }