| /* |
| * 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 |
| // } |
| //} |