blob: fb1d27005a8eb7ac13d6563214c2b4ca01b7669e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dubbo
import (
log "github.com/dubbogo/gost/log/logger"
)
import (
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config"
"dubbo.apache.org/dubbo-go/v3/config_center"
"dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/graceful_shutdown"
"dubbo.apache.org/dubbo-go/v3/logger"
"dubbo.apache.org/dubbo-go/v3/metadata"
"dubbo.apache.org/dubbo-go/v3/metrics"
"dubbo.apache.org/dubbo-go/v3/otel/trace"
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/registry"
)
type InstanceOptions struct {
Application *global.ApplicationConfig `validate:"required" yaml:"application" json:"application,omitempty" property:"application"`
Protocols map[string]*global.ProtocolConfig `validate:"required" yaml:"protocols" json:"protocols" property:"protocols"`
Registries map[string]*global.RegistryConfig `yaml:"registries" json:"registries" property:"registries"`
ConfigCenter *global.CenterConfig `yaml:"config-center" json:"config-center,omitempty"`
MetadataReport *global.MetadataReportConfig `yaml:"metadata-report" json:"metadata-report,omitempty" property:"metadata-report"`
Provider *global.ProviderConfig `yaml:"provider" json:"provider" property:"provider"`
Consumer *global.ConsumerConfig `yaml:"consumer" json:"consumer" property:"consumer"`
Metrics *global.MetricsConfig `yaml:"metrics" json:"metrics,omitempty" property:"metrics"`
Otel *global.OtelConfig `yaml:"otel" json:"otel,omitempty" property:"otel"`
Logger *global.LoggerConfig `yaml:"logger" json:"logger,omitempty" property:"logger"`
Shutdown *global.ShutdownConfig `yaml:"shutdown" json:"shutdown,omitempty" property:"shutdown"`
// todo(DMwangnima): router feature would be supported in the future
//Router []*RouterConfig `yaml:"router" json:"router,omitempty" property:"router"`
EventDispatcherType string `default:"direct" yaml:"event-dispatcher-type" json:"event-dispatcher-type,omitempty"`
CacheFile string `yaml:"cache_file" json:"cache_file,omitempty" property:"cache_file"`
Custom *global.CustomConfig `yaml:"custom" json:"custom,omitempty" property:"custom"`
Profiles *global.ProfilesConfig `yaml:"profiles" json:"profiles,omitempty" property:"profiles"`
TLSConfig *global.TLSConfig `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`
}
func defaultInstanceOptions() *InstanceOptions {
return &InstanceOptions{
Application: global.DefaultApplicationConfig(),
Protocols: make(map[string]*global.ProtocolConfig),
Registries: make(map[string]*global.RegistryConfig),
ConfigCenter: global.DefaultCenterConfig(),
MetadataReport: global.DefaultMetadataReportConfig(),
Provider: global.DefaultProviderConfig(),
Consumer: global.DefaultConsumerConfig(),
Metrics: global.DefaultMetricsConfig(),
Otel: global.DefaultOtelConfig(),
Logger: global.DefaultLoggerConfig(),
Shutdown: global.DefaultShutdownConfig(),
Custom: global.DefaultCustomConfig(),
Profiles: global.DefaultProfilesConfig(),
TLSConfig: global.DefaultTLSConfig(),
}
}
func (rc *InstanceOptions) init(opts ...InstanceOption) error {
for _, opt := range opts {
opt(rc)
}
// remaining procedure is like RootConfig.Init() without RootConfig.Start()
// tasks of RootConfig.Start() would be decomposed to Client and Server
rcCompat := compatRootConfig(rc)
if err := rcCompat.Logger.Init(); err != nil { // init default logger
return err
}
if err := rcCompat.ConfigCenter.Init(rcCompat); err != nil {
log.Infof("[Config Center] Config center doesn't start")
log.Debugf("config center doesn't start because %s", err)
} else {
compatInstanceOptions(rcCompat, rc)
if err = rcCompat.Logger.Init(); err != nil { // init logger using config from config center again
return err
}
}
if err := rcCompat.Application.Init(); err != nil {
return err
}
// init user define
if err := rcCompat.Custom.Init(); err != nil {
return err
}
// init protocol
protocols := rcCompat.Protocols
if len(protocols) <= 0 {
protocol := &config.ProtocolConfig{}
protocols = make(map[string]*config.ProtocolConfig, 1)
protocols[constant.Dubbo] = protocol
rcCompat.Protocols = protocols
}
for _, protocol := range protocols {
if err := protocol.Init(); err != nil {
return err
}
}
// init registry
registries := rcCompat.Registries
if registries != nil {
for _, reg := range registries {
if err := reg.Init(); err != nil {
return err
}
}
}
if err := rcCompat.MetadataReport.Init(rcCompat); err != nil {
return err
}
if err := rcCompat.Metrics.Init(rcCompat); err != nil {
return err
}
if err := rcCompat.Otel.Init(rcCompat.Application); err != nil {
return err
}
routers := rcCompat.Router
if len(routers) > 0 {
for _, r := range routers {
if err := r.Init(); err != nil {
return err
}
}
rcCompat.Router = routers
}
// provider、consumer must last init
if err := rcCompat.Provider.Init(rcCompat); err != nil {
return err
}
if err := rcCompat.Consumer.Init(rcCompat); err != nil {
return err
}
if err := rcCompat.Shutdown.Init(); err != nil {
return err
}
config.SetRootConfig(*rcCompat)
return nil
}
func (rc *InstanceOptions) Prefix() string {
return constant.Dubbo
}
func (rc *InstanceOptions) CloneApplication() *global.ApplicationConfig {
if rc.Application == nil {
return nil
}
return rc.Application.Clone()
}
func (rc *InstanceOptions) CloneProtocols() map[string]*global.ProtocolConfig {
if rc.Protocols == nil {
return nil
}
protocols := make(map[string]*global.ProtocolConfig, len(rc.Protocols))
for k, v := range rc.Protocols {
protocols[k] = v.Clone()
}
return protocols
}
func (rc *InstanceOptions) CloneRegistries() map[string]*global.RegistryConfig {
if rc.Registries == nil {
return nil
}
registries := make(map[string]*global.RegistryConfig, len(rc.Registries))
for k, v := range rc.Registries {
registries[k] = v.Clone()
}
return registries
}
func (rc *InstanceOptions) CloneConfigCenter() *global.CenterConfig {
if rc.ConfigCenter == nil {
return nil
}
return rc.ConfigCenter.Clone()
}
func (rc *InstanceOptions) CloneMetadataReport() *global.MetadataReportConfig {
if rc.MetadataReport == nil {
return nil
}
return rc.MetadataReport.Clone()
}
func (rc *InstanceOptions) CloneProvider() *global.ProviderConfig {
if rc.Provider == nil {
return nil
}
return rc.Provider.Clone()
}
func (rc *InstanceOptions) CloneConsumer() *global.ConsumerConfig {
if rc.Consumer == nil {
return nil
}
return rc.Consumer.Clone()
}
func (rc *InstanceOptions) CloneMetrics() *global.MetricsConfig {
if rc.Metrics == nil {
return nil
}
return rc.Metrics.Clone()
}
func (rc *InstanceOptions) CloneOtel() *global.OtelConfig {
if rc.Otel == nil {
return nil
}
return rc.Otel.Clone()
}
func (rc *InstanceOptions) CloneLogger() *global.LoggerConfig {
if rc.Logger == nil {
return nil
}
return rc.Logger.Clone()
}
func (rc *InstanceOptions) CloneShutdown() *global.ShutdownConfig {
if rc.Shutdown == nil {
return nil
}
return rc.Shutdown.Clone()
}
func (rc *InstanceOptions) CloneCustom() *global.CustomConfig {
if rc.Custom == nil {
return nil
}
return rc.Custom.Clone()
}
func (rc *InstanceOptions) CloneProfiles() *global.ProfilesConfig {
if rc.Profiles == nil {
return nil
}
return rc.Profiles.Clone()
}
func (rc *InstanceOptions) CloneTLSConfig() *global.TLSConfig {
if rc.TLSConfig == nil {
return nil
}
return rc.TLSConfig.Clone()
}
type InstanceOption func(*InstanceOptions)
func WithOrganization(organization string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Organization = organization
}
}
func WithName(name string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Name = name
}
}
func WithModule(module string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Module = module
}
}
func WithGroup(group string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Group = group
}
}
func WithVersion(version string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Version = version
}
}
func WithOwner(owner string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Owner = owner
}
}
func WithEnvironment(environment string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Environment = environment
}
}
func WithRemoteMetadata() InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.MetadataType = constant.RemoteMetadataStorageType
}
}
func WithTag(tag string) InstanceOption {
return func(opts *InstanceOptions) {
opts.Application.Tag = tag
}
}
func WithProtocol(opts ...protocol.Option) InstanceOption {
proOpts := protocol.NewOptions(opts...)
return func(insOpts *InstanceOptions) {
if insOpts.Protocols == nil {
insOpts.Protocols = make(map[string]*global.ProtocolConfig)
}
insOpts.Protocols[proOpts.ID] = proOpts.Protocol
}
}
func WithRegistry(opts ...registry.Option) InstanceOption {
regOpts := registry.NewOptions(opts...)
return func(insOpts *InstanceOptions) {
if insOpts.Registries == nil {
insOpts.Registries = make(map[string]*global.RegistryConfig)
}
insOpts.Registries[regOpts.ID] = regOpts.Registry
}
}
// WithTracing otel configuration, currently only supports tracing
func WithTracing(opts ...trace.Option) InstanceOption {
traceOpts := trace.NewOptions(opts...)
return func(insOpts *InstanceOptions) {
insOpts.Otel.TracingConfig = traceOpts.Otel.TracingConfig
}
}
func WithConfigCenter(opts ...config_center.Option) InstanceOption {
configOpts := config_center.NewOptions(opts...)
return func(cfg *InstanceOptions) {
cfg.ConfigCenter = configOpts.Center
}
}
func WithMetadataReport(opts ...metadata.Option) InstanceOption {
metadataOpts := metadata.NewOptions(opts...)
return func(cfg *InstanceOptions) {
cfg.MetadataReport = metadataOpts.Metadata
}
}
func WithMetrics(opts ...metrics.Option) InstanceOption {
metricOpts := metrics.NewOptions(opts...)
return func(cfg *InstanceOptions) {
cfg.Metrics = metricOpts.Metrics
}
}
func WithLogger(opts ...logger.Option) InstanceOption {
loggerOpts := logger.NewOptions(opts...)
return func(cfg *InstanceOptions) {
cfg.Logger = loggerOpts.Logger
}
}
func WithShutdown(opts ...graceful_shutdown.Option) InstanceOption {
sdOpts := graceful_shutdown.NewOptions(opts...)
return func(insOpts *InstanceOptions) {
insOpts.Shutdown = sdOpts.Shutdown
}
}
// todo(DMwangnima): enumerate specific EventDispatcherType
//func WithEventDispatcherType(typ string) InstanceOption {
// return func(cfg *InstanceOptions) {
// cfg.EventDispatcherType = typ
// }
//}
//func WithCacheFile(file string) InstanceOption {
// return func(cfg *InstanceOptions) {
// cfg.CacheFile = file
// }
//}
//func WithCustom(opts ...global.CustomOption) InstanceOption {
// cusCfg := new(global.CustomConfig)
// for _, opt := range opts {
// opt(cusCfg)
// }
//
// return func(cfg *InstanceOptions) {
// cfg.Custom = cusCfg
// }
//}
//func WithProfiles(opts ...global.ProfilesOption) InstanceOption {
// proCfg := new(global.ProfilesConfig)
// for _, opt := range opts {
// opt(proCfg)
// }
//
// return func(cfg *InstanceOptions) {
// cfg.Profiles = proCfg
// }
//}
//func WithTLS(opts ...global.TLSOption) InstanceOption {
// tlsCfg := new(global.TLSConfig)
// for _, opt := range opts {
// opt(tlsCfg)
// }
//
// return func(cfg *InstanceOptions) {
// cfg.TLSConfig = tlsCfg
// }
//}