| /* |
| * 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 config |
| |
| import ( |
| "fmt" |
| "strings" |
| ) |
| |
| import ( |
| "github.com/creasty/defaults" |
| |
| "github.com/dubbogo/gost/log/logger" |
| |
| tripleConstant "github.com/dubbogo/triple/pkg/common/constant" |
| |
| perrors "github.com/pkg/errors" |
| ) |
| |
| import ( |
| "dubbo.apache.org/dubbo-go/v3/common" |
| "dubbo.apache.org/dubbo-go/v3/common/constant" |
| aslimiter "dubbo.apache.org/dubbo-go/v3/filter/adaptivesvc/limiter" |
| ) |
| |
| // ProviderConfig is the default configuration of service provider |
| type ProviderConfig struct { |
| Filter string `yaml:"filter" json:"filter,omitempty" property:"filter"` |
| // Deprecated Register whether registration is required |
| Register bool `yaml:"register" json:"register" property:"register"` |
| // RegistryIDs is registry ids list |
| RegistryIDs []string `yaml:"registry-ids" json:"registry-ids" property:"registry-ids"` |
| // protocol |
| ProtocolIDs []string `yaml:"protocol-ids" json:"protocol-ids" property:"protocol-ids"` |
| // TracingKey is tracing ids list |
| TracingKey string `yaml:"tracing-key" json:"tracing-key" property:"tracing-key"` |
| // Services services |
| Services map[string]*ServiceConfig `yaml:"services" json:"services,omitempty" property:"services"` |
| ProxyFactory string `default:"default" yaml:"proxy" json:"proxy,omitempty" property:"proxy"` |
| FilterConf interface{} `yaml:"filter_conf" json:"filter_conf,omitempty" property:"filter_conf"` |
| ConfigType map[string]string `yaml:"config_type" json:"config_type,omitempty" property:"config_type"` |
| // adaptive service |
| AdaptiveService bool `yaml:"adaptive-service" json:"adaptive-service" property:"adaptive-service"` |
| AdaptiveServiceVerbose bool `yaml:"adaptive-service-verbose" json:"adaptive-service-verbose" property:"adaptive-service-verbose"` |
| |
| rootConfig *RootConfig |
| } |
| |
| func (ProviderConfig) Prefix() string { |
| return constant.ProviderConfigPrefix |
| } |
| |
| func (c *ProviderConfig) check() error { |
| if err := defaults.Set(c); err != nil { |
| return err |
| } |
| return verify(c) |
| } |
| |
| func (c *ProviderConfig) Init(rc *RootConfig) error { |
| if c == nil { |
| return nil |
| } |
| buildDebugMsg := func() string { |
| if len(c.Services) == 0 { |
| return "empty" |
| } |
| providerNames := make([]string, 0, len(c.Services)) |
| for k := range c.Services { |
| providerNames = append(providerNames, k) |
| } |
| return strings.Join(providerNames, ", ") |
| } |
| logger.Debugf("Registered provider services are %v", buildDebugMsg()) |
| |
| c.RegistryIDs = translateIds(c.RegistryIDs) |
| if len(c.RegistryIDs) <= 0 { |
| c.RegistryIDs = rc.getRegistryIds() |
| } |
| c.ProtocolIDs = translateIds(c.ProtocolIDs) |
| |
| if c.TracingKey == "" && len(rc.Tracing) > 0 { |
| for k := range rc.Tracing { |
| c.TracingKey = k |
| break |
| } |
| } |
| for key, serviceConfig := range c.Services { |
| if serviceConfig.Interface == "" { |
| service := GetProviderService(key) |
| // try to use interface name defined by pb |
| supportPBPackagerNameSerivce, ok := service.(common.TriplePBService) |
| if !ok { |
| logger.Errorf("Service with reference = %s is not support read interface name from it."+ |
| "Please run go install github.com/dubbogo/dubbogo-cli/cmd/protoc-gen-go-triple@latest to update your "+ |
| "protoc-gen-go-triple and re-generate your pb file again."+ |
| "If you are not using pb serialization, please set 'interface' field in service config.", key) |
| continue |
| } else { |
| // use interface name defined by pb |
| serviceConfig.Interface = supportPBPackagerNameSerivce.XXX_InterfaceName() |
| } |
| } |
| if err := serviceConfig.Init(rc); err != nil { |
| return err |
| } |
| |
| serviceConfig.adaptiveService = c.AdaptiveService |
| } |
| |
| for k, v := range rc.Protocols { |
| if v.Name == tripleConstant.TRIPLE { |
| // Auto create grpc based health check service. |
| //healthService := NewServiceConfigBuilder(). |
| // SetProtocolIDs(k). |
| // SetNotRegister(true). |
| // SetInterface(constant.HealthCheckServiceInterface). |
| // Build() |
| //if err := healthService.Init(rc); err != nil { |
| // return err |
| //} |
| //c.Services[constant.HealthCheckServiceTypeName] = healthService |
| |
| // Auto create reflection service configure only when provider with triple service is configured. |
| tripleReflectionService := NewServiceConfigBuilder(). |
| SetProtocolIDs(k). |
| SetNotRegister(true). |
| SetInterface(constant.ReflectionServiceInterface). |
| Build() |
| if err := tripleReflectionService.Init(rc); err != nil { |
| return err |
| } |
| // Maybe only register once, If setting this service, break from traversing Protocols. |
| c.Services[constant.ReflectionServiceTypeName] = tripleReflectionService |
| break |
| } |
| } |
| |
| if err := c.check(); err != nil { |
| return err |
| } |
| // enable adaptive service verbose |
| if c.AdaptiveServiceVerbose { |
| if !c.AdaptiveService { |
| return perrors.Errorf("The adaptive service is disabled, " + |
| "adaptive service verbose should be disabled either.") |
| } |
| logger.Infof("adaptive service verbose is enabled.") |
| logger.Debugf("debug-level info could be shown.") |
| aslimiter.Verbose = true |
| } |
| return nil |
| } |
| |
| func (c *ProviderConfig) Load() { |
| for registeredTypeName, service := range GetProviderServiceMap() { |
| serviceConfig, ok := c.Services[registeredTypeName] |
| if !ok { |
| if registeredTypeName == constant.ReflectionServiceTypeName || |
| registeredTypeName == constant.HealthCheckServiceTypeName { |
| // do not auto generate reflection or health check server's configuration. |
| continue |
| } |
| // service doesn't config in config file, create one with default |
| supportPBPackagerNameSerivce, ok := service.(common.TriplePBService) |
| if !ok { |
| logger.Warnf( |
| "The provider service %s is ignored: neither the config is found, nor it is a valid Triple service.", |
| registeredTypeName) |
| continue |
| } |
| serviceConfig = NewServiceConfigBuilder().Build() |
| // use interface name defined by pb |
| serviceConfig.Interface = supportPBPackagerNameSerivce.XXX_InterfaceName() |
| if err := serviceConfig.Init(rootConfig); err != nil { |
| logger.Errorf("Service with refKey = %s init failed with error = %s") |
| } |
| serviceConfig.adaptiveService = c.AdaptiveService |
| } |
| serviceConfig.id = registeredTypeName |
| serviceConfig.Implement(service) |
| if err := serviceConfig.Export(); err != nil { |
| logger.Errorf(fmt.Sprintf("service with registeredTypeName = %s export failed! err: %#v", registeredTypeName, err)) |
| } |
| } |
| } |
| |
| // newEmptyProviderConfig returns ProviderConfig with default ApplicationConfig |
| func newEmptyProviderConfig() *ProviderConfig { |
| newProviderConfig := &ProviderConfig{ |
| Services: make(map[string]*ServiceConfig), |
| RegistryIDs: make([]string, 8), |
| ProtocolIDs: make([]string, 8), |
| } |
| return newProviderConfig |
| } |
| |
| type ProviderConfigBuilder struct { |
| providerConfig *ProviderConfig |
| } |
| |
| func NewProviderConfigBuilder() *ProviderConfigBuilder { |
| return &ProviderConfigBuilder{providerConfig: newEmptyProviderConfig()} |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetFilter(filter string) *ProviderConfigBuilder { |
| pcb.providerConfig.Filter = filter |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetRegister(register bool) *ProviderConfigBuilder { |
| pcb.providerConfig.Register = register |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetRegistryIDs(RegistryIDs ...string) *ProviderConfigBuilder { |
| pcb.providerConfig.RegistryIDs = RegistryIDs |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetServices(services map[string]*ServiceConfig) *ProviderConfigBuilder { |
| pcb.providerConfig.Services = services |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) AddService(serviceID string, serviceConfig *ServiceConfig) *ProviderConfigBuilder { |
| if pcb.providerConfig.Services == nil { |
| pcb.providerConfig.Services = make(map[string]*ServiceConfig) |
| } |
| pcb.providerConfig.Services[serviceID] = serviceConfig |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetProxyFactory(proxyFactory string) *ProviderConfigBuilder { |
| pcb.providerConfig.ProxyFactory = proxyFactory |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetFilterConf(filterConf interface{}) *ProviderConfigBuilder { |
| pcb.providerConfig.FilterConf = filterConf |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetConfigType(configType map[string]string) *ProviderConfigBuilder { |
| pcb.providerConfig.ConfigType = configType |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) AddConfigType(key, value string) *ProviderConfigBuilder { |
| if pcb.providerConfig.ConfigType == nil { |
| pcb.providerConfig.ConfigType = make(map[string]string) |
| } |
| pcb.providerConfig.ConfigType[key] = value |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) SetRootConfig(rootConfig *RootConfig) *ProviderConfigBuilder { |
| pcb.providerConfig.rootConfig = rootConfig |
| return pcb |
| } |
| |
| func (pcb *ProviderConfigBuilder) Build() *ProviderConfig { |
| return pcb.providerConfig |
| } |