config/metadata_config.go (193 lines of code) (raw):

/* * 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 ( "strconv" "time" ) import ( "github.com/dubbogo/gost/log/logger" perrors "github.com/pkg/errors" ) import ( "dubbo.apache.org/dubbo-go/v3/common" "dubbo.apache.org/dubbo-go/v3/common/constant" "dubbo.apache.org/dubbo-go/v3/metadata" ) // MetadataReportConfig is app level configuration type MetadataReportConfig struct { Protocol string `required:"true" yaml:"protocol" json:"protocol,omitempty"` Address string `required:"true" yaml:"address" json:"address"` Username string `yaml:"username" json:"username,omitempty"` Password string `yaml:"password" json:"password,omitempty"` Timeout string `yaml:"timeout" json:"timeout,omitempty"` Group string `yaml:"group" json:"group,omitempty"` Namespace string `yaml:"namespace" json:"namespace,omitempty"` Params map[string]string `yaml:"params" json:"parameters,omitempty"` // metadataType of this application is defined by application config, local or remote metadataType string } func initMetadata(rc *RootConfig) error { opts := metadata.NewOptions( metadata.WithAppName(rc.Application.Name), metadata.WithMetadataType(rc.Application.MetadataType), metadata.WithPort(getMetadataPort(rc)), ) if err := opts.Init(); err != nil { return err } return nil } func getMetadataPort(rc *RootConfig) int { port := rc.Application.MetadataServicePort if port == "" { protocolConfig, ok := rootConfig.Protocols[constant.DefaultProtocol] if ok { port = protocolConfig.Port } else { logger.Warnf("[Metadata Service] Dubbo-go %s version's MetadataService only support dubbo protocol,"+ "MetadataService will use random port", constant.Version) } } if port == "" { return 0 } p, err := strconv.Atoi(port) if err != nil { logger.Error("MetadataService port parse error %v, MetadataService will use random port", err) return 0 } return p } // Prefix dubbo.consumer func (*MetadataReportConfig) Prefix() string { return constant.MetadataReportPrefix } func (mc *MetadataReportConfig) toReportOptions() (*metadata.ReportOptions, error) { opts := metadata.NewReportOptions( metadata.WithRegistryId(constant.DefaultKey), metadata.WithProtocol(mc.Protocol), metadata.WithAddress(mc.Address), metadata.WithUsername(mc.Username), metadata.WithPassword(mc.Password), metadata.WithGroup(mc.Group), metadata.WithNamespace(mc.Namespace), metadata.WithParams(mc.Params), ) if mc.Timeout != "" { timeout, err := time.ParseDuration(mc.Timeout) if err != nil { return nil, err } metadata.WithTimeout(timeout)(opts) } return opts, nil } func registryToReportOptions(id string, rc *RegistryConfig) (*metadata.ReportOptions, error) { opts := metadata.NewReportOptions( metadata.WithRegistryId(id), metadata.WithProtocol(rc.Protocol), metadata.WithAddress(rc.Address), metadata.WithUsername(rc.Username), metadata.WithPassword(rc.Password), metadata.WithGroup(rc.Group), metadata.WithNamespace(rc.Namespace), metadata.WithParams(rc.Params), ) if rc.Timeout != "" { timeout, err := time.ParseDuration(rc.Timeout) if err != nil { return nil, err } metadata.WithTimeout(timeout)(opts) } return opts, nil } func (mc *MetadataReportConfig) Init(rc *RootConfig) error { if mc == nil { return nil } mc.metadataType = rc.Application.MetadataType if mc.Address != "" { // if metadata report config is avaible, then init metadata report instance opts, err := mc.toReportOptions() if err != nil { return err } return opts.Init() } if rc.Registries != nil && len(rc.Registries) > 0 { // if metadata report config is not available, then init metadata report instance with registries for id, reg := range rc.Registries { if isValid(reg.Address) { ok, err := strconv.ParseBool(reg.UseAsMetaReport) if err != nil { return err } if ok { opts, err := registryToReportOptions(id, reg) if err != nil { return err } if err = opts.Init(); err != nil { return err } } } } } return nil } func (mc *MetadataReportConfig) ToUrl() (*common.URL, error) { res, err := common.NewURL(mc.Address, common.WithUsername(mc.Username), common.WithPassword(mc.Password), common.WithLocation(mc.Address), common.WithProtocol(mc.Protocol), common.WithParamsValue(constant.TimeoutKey, mc.Timeout), common.WithParamsValue(constant.MetadataReportGroupKey, mc.Group), common.WithParamsValue(constant.MetadataReportNamespaceKey, mc.Namespace), common.WithParamsValue(constant.MetadataTypeKey, mc.metadataType), common.WithParamsValue(constant.ClientNameKey, clientNameID(mc, mc.Protocol, mc.Address)), ) if err != nil || len(res.Protocol) == 0 { return nil, perrors.New("Invalid MetadataReport Config.") } res.SetParam("metadata", res.Protocol) for key, val := range mc.Params { res.SetParam(key, val) } return res, nil } type MetadataReportConfigBuilder struct { metadataReportConfig *MetadataReportConfig } func NewMetadataReportConfigBuilder() *MetadataReportConfigBuilder { return &MetadataReportConfigBuilder{metadataReportConfig: newEmptyMetadataReportConfig()} } func (mrcb *MetadataReportConfigBuilder) SetProtocol(protocol string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Protocol = protocol return mrcb } func (mrcb *MetadataReportConfigBuilder) SetAddress(address string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Address = address return mrcb } func (mrcb *MetadataReportConfigBuilder) SetUsername(username string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Username = username return mrcb } func (mrcb *MetadataReportConfigBuilder) SetPassword(password string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Password = password return mrcb } func (mrcb *MetadataReportConfigBuilder) SetTimeout(timeout string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Timeout = timeout return mrcb } func (mrcb *MetadataReportConfigBuilder) SetGroup(group string) *MetadataReportConfigBuilder { mrcb.metadataReportConfig.Group = group return mrcb } func (mrcb *MetadataReportConfigBuilder) Build() *MetadataReportConfig { return mrcb.metadataReportConfig } func newEmptyMetadataReportConfig() *MetadataReportConfig { return &MetadataReportConfig{ Params: make(map[string]string), } }