blob: 2be01844195b00d0c65259b28b093e0f6a375d86 [file]
/*
* 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 client
import (
"strconv"
"time"
)
import (
"github.com/creasty/defaults"
)
import (
"dubbo.apache.org/dubbo-go/v3/common"
commonCfg "dubbo.apache.org/dubbo-go/v3/common/config"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/global"
"dubbo.apache.org/dubbo-go/v3/graceful_shutdown"
"dubbo.apache.org/dubbo-go/v3/internal"
"dubbo.apache.org/dubbo-go/v3/protocol"
"dubbo.apache.org/dubbo-go/v3/protocol/base"
"dubbo.apache.org/dubbo-go/v3/proxy"
"dubbo.apache.org/dubbo-go/v3/registry"
"dubbo.apache.org/dubbo-go/v3/tls"
)
type ReferenceOptions struct {
Reference *global.ReferenceConfig
Consumer *global.ConsumerConfig
Application *global.ApplicationConfig
Shutdown *global.ShutdownConfig
Metrics *global.MetricsConfig
Otel *global.OtelConfig
TLS *global.TLSConfig
Protocols map[string]*global.ProtocolConfig
Registries map[string]*global.RegistryConfig
Routers []*global.RouterConfig
pxy *proxy.Proxy
id string
invoker base.Invoker
urls []*common.URL
metaDataType string
info *ClientInfo
}
func defaultReferenceOptions() *ReferenceOptions {
return &ReferenceOptions{
Reference: global.DefaultReferenceConfig(),
Application: global.DefaultApplicationConfig(),
Shutdown: global.DefaultShutdownConfig(),
Metrics: global.DefaultMetricsConfig(),
Otel: global.DefaultOtelConfig(),
TLS: global.DefaultTLSConfig(),
Protocols: make(map[string]*global.ProtocolConfig),
Registries: global.DefaultRegistriesConfig(),
}
}
func (refOpts *ReferenceOptions) init(opts ...ReferenceOption) error {
for _, opt := range opts {
opt(refOpts)
}
if err := defaults.Set(refOpts); err != nil {
return err
}
refConf := refOpts.Reference
app := refOpts.Application
if app != nil {
refOpts.metaDataType = app.MetadataType
if refConf.Group == "" {
refConf.Group = app.Group
}
if refConf.Version == "" {
refConf.Version = app.Version
}
}
// init method
if refConf.MethodsConfig == nil {
refConf.MethodsConfig = make([]*global.MethodConfig, 0)
} else {
for _, method := range refConf.MethodsConfig {
if err := internal.ValidateMethodConfig(method); err != nil {
return err
}
}
}
// init cluster
if refConf.Cluster == "" {
refConf.Cluster = constant.ClusterKeyFailover
}
// init registries
if len(refOpts.Registries) > 0 {
regs := refOpts.Registries
if len(refConf.RegistryIDs) <= 0 {
refConf.RegistryIDs = make([]string, 0, len(regs))
for key := range regs {
refConf.RegistryIDs = append(refConf.RegistryIDs, key)
}
}
refConf.RegistryIDs = commonCfg.TranslateIds(refConf.RegistryIDs)
if err := internal.ValidateRegistryIDs(refConf.RegistryIDs, regs); err != nil {
return err
}
}
// init protocol
if refConf.Protocol == "" {
refConf.Protocol = constant.TriProtocol
if refOpts.Consumer != nil && refOpts.Consumer.Protocol != "" {
refConf.Protocol = refOpts.Consumer.Protocol
}
}
// init serialization
if refConf.Serialization == "" {
refConf.Serialization = constant.ProtobufSerialization
}
return commonCfg.Verify(refOpts)
}
type ReferenceOption func(*ReferenceOptions)
// ---------- For user ----------
func WithCheck() ReferenceOption {
return func(opts *ReferenceOptions) {
check := true
opts.Reference.Check = &check
}
}
func WithURL(url string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.URL = url
}
}
func WithFilter(filter string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Filter = filter
}
}
// WithInterface sets the interface name for the service reference.
//
// As a functional option, it is passed to a client constructor
// (e.g., NewGreetService) to configure which remote service to connect to.
//
// The interfaceName is a crucial identifier for service discovery and routing,
// and it must exactly match the name registered by the service provider.
//
// Usage:
//
// svc, err := greet.NewGreetService(
// cli,
// client.WithInterface("com.your.company.GreetService"),
// )
func WithInterface(interfaceName string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.InterfaceName = interfaceName
}
}
func WithRegistryIDs(registryIDs ...string) ReferenceOption {
return func(opts *ReferenceOptions) {
if len(registryIDs) > 0 {
opts.Reference.RegistryIDs = registryIDs
}
}
}
func WithRegistry(opts ...registry.Option) ReferenceOption {
regOpts := registry.NewOptions(opts...)
return func(refOpts *ReferenceOptions) {
if refOpts.Registries == nil {
refOpts.Registries = make(map[string]*global.RegistryConfig)
}
refOpts.Registries[regOpts.ID] = regOpts.Registry
}
}
// ========== Cluster Strategy ==========
func WithClusterAvailable() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyAvailable
}
}
func WithClusterBroadcast() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyBroadcast
}
}
func WithClusterFailBack() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyFailback
}
}
func WithClusterFailFast() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyFailfast
}
}
func WithClusterFailOver() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyFailover
}
}
func WithClusterFailSafe() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyFailsafe
}
}
func WithClusterForking() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyForking
}
}
func WithClusterZoneAware() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyZoneAware
}
}
func WithClusterAdaptiveService() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = constant.ClusterKeyAdaptiveService
}
}
func WithCluster(cluster string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Cluster = cluster
}
}
// ========== LoadBalance Strategy ==========
func WithLoadBalanceConsistentHashing() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = constant.LoadBalanceKeyConsistentHashing
}
}
func WithLoadBalanceLeastActive() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = constant.LoadBalanceKeyLeastActive
}
}
func WithLoadBalanceRandom() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = constant.LoadBalanceKeyRandom
}
}
func WithLoadBalanceRoundRobin() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = constant.LoadBalanceKeyRoundRobin
}
}
func WithLoadBalanceP2C() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = constant.LoadBalanceKeyP2C
}
}
func WithLoadBalance(lb string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Loadbalance = lb
}
}
func WithRetries(retries int) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Retries = strconv.Itoa(retries)
}
}
func WithGroup(group string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Group = group
}
}
func WithVersion(version string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Version = version
}
}
func WithSerializationJSON() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Serialization = constant.JSONSerialization
}
}
func WithSerialization(serialization string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Serialization = serialization
}
}
func WithProvidedBy(providedBy string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.ProvidedBy = providedBy
}
}
func WithAsync() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Async = true
}
}
func WithParams(params map[string]string) ReferenceOption {
return func(opts *ReferenceOptions) {
if len(params) <= 0 {
return
}
opts.Reference.Params = params
}
}
func WithGeneric() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Generic = "true"
}
}
// WithGenericType sets the generic serialization type for generic call
// Valid values: "true" (default), "gson", "protobuf", "protobuf-json"
func WithGenericType(genericType string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Generic = genericType
}
}
func WithSticky() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Sticky = true
}
}
// TODO: remove this function after old triple removed
func WithIDL(IDLMode string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.IDLMode = IDLMode
}
}
// ========== Protocol to consume ==========
func WithProtocolDubbo() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Protocol = constant.DubboProtocol
}
}
func WithProtocolTriple() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Protocol = constant.TriProtocol
}
}
func WithProtocolJsonRPC() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Protocol = constant.JSONRPCProtocol
}
}
func WithProtocol(protocol string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.Protocol = protocol
}
}
func WithRequestTimeout(timeout time.Duration) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.RequestTimeout = timeout.String()
}
}
func WithForceTag() ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.ForceTag = true
}
}
func WithMeshProviderPort(port int) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.MeshProviderPort = port
}
}
func WithMethod(method *global.MethodConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
if method == nil {
return
}
if opts.Reference.MethodsConfig == nil {
opts.Reference.MethodsConfig = make([]*global.MethodConfig, 0)
}
opts.Reference.MethodsConfig = append(opts.Reference.MethodsConfig, method)
}
}
func WithParam(k, v string) ReferenceOption {
return func(opts *ReferenceOptions) {
if opts.Reference.Params == nil {
opts.Reference.Params = make(map[string]string)
}
opts.Reference.Params[k] = v
}
}
// WithRouter appends router configurations to the reference options.
// This is a user-facing option for incrementally adding routers.
// It appends to the current router config slice instead of replacing it.
func WithRouter(routers ...*global.RouterConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
if len(routers) > 0 {
opts.Routers = append(opts.Routers, routers...)
}
}
}
// ---------- For framework ----------
// These functions should not be invoked by users
func setReference(reference *global.ReferenceConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference = reference
}
}
func setInterfaceName(interfaceName string) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Reference.InterfaceName = interfaceName
}
}
func setConsumer(consumer *global.ConsumerConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Consumer = consumer
}
}
func setMetrics(mc *global.MetricsConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Metrics = mc
}
}
func setOtel(oc *global.OtelConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Otel = oc
}
}
func setTLS(tls *global.TLSConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.TLS = tls
}
}
func setApplication(application *global.ApplicationConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Application = application
}
}
// setProtocols sets the protocols configuration for the service reference.
// This is an internal function used by the framework to configure protocol settings.
// It accepts a map of protocol configurations where the key is the protocol name
// and the value is the corresponding protocol configuration.
func setProtocols(protocols map[string]*global.ProtocolConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Protocols = protocols
}
}
func setShutdown(shutdown *global.ShutdownConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Shutdown = shutdown
}
}
func setRegistries(regs map[string]*global.RegistryConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Registries = regs
}
}
// setRouters sets the routers configuration for the service reference.
// This is an internal framework function for applying router settings to
// reference options. It replaces the current router slice.
func setRouters(routers []*global.RouterConfig) ReferenceOption {
return func(opts *ReferenceOptions) {
opts.Routers = routers
}
}
type ClientOptions struct {
Consumer *global.ConsumerConfig
Application *global.ApplicationConfig
Registries map[string]*global.RegistryConfig
Shutdown *global.ShutdownConfig
Metrics *global.MetricsConfig
Otel *global.OtelConfig
TLS *global.TLSConfig
Protocols map[string]*global.ProtocolConfig
Routers []*global.RouterConfig
overallReference *global.ReferenceConfig
}
func defaultClientOptions() *ClientOptions {
return &ClientOptions{
Consumer: global.DefaultConsumerConfig(),
Registries: global.DefaultRegistriesConfig(),
Application: global.DefaultApplicationConfig(),
Shutdown: global.DefaultShutdownConfig(),
Metrics: global.DefaultMetricsConfig(),
Otel: global.DefaultOtelConfig(),
TLS: global.DefaultTLSConfig(),
overallReference: global.DefaultReferenceConfig(),
}
}
func (cliOpts *ClientOptions) init(opts ...ClientOption) error {
for _, opt := range opts {
opt(cliOpts)
}
if err := defaults.Set(cliOpts); err != nil {
return err
}
consumerConf := cliOpts.Consumer
// init registries
regs := cliOpts.Registries
if len(regs) > 0 {
if len(consumerConf.RegistryIDs) <= 0 {
consumerConf.RegistryIDs = make([]string, 0, len(regs))
for key := range regs {
consumerConf.RegistryIDs = append(consumerConf.RegistryIDs, key)
}
}
consumerConf.RegistryIDs = commonCfg.TranslateIds(consumerConf.RegistryIDs)
if err := internal.ValidateRegistryIDs(consumerConf.RegistryIDs, regs); err != nil {
return err
}
}
// init cluster
if cliOpts.overallReference.Cluster == "" {
cliOpts.overallReference.Cluster = constant.ClusterKeyFailover
}
// init protocol
if cliOpts.Consumer.Protocol == "" {
cliOpts.Consumer.Protocol = constant.TriProtocol
}
// init serialization
if cliOpts.overallReference.Serialization == "" {
cliOpts.overallReference.Serialization = constant.ProtobufSerialization
}
// todo(DMwangnima): is there any part that we should do compatibility processing?
// init overallReference from Consumer config
if consumerConf != nil {
if cliOpts.overallReference.Filter == "" {
cliOpts.overallReference.Filter = consumerConf.Filter
}
if len(cliOpts.overallReference.RegistryIDs) <= 0 {
cliOpts.overallReference.RegistryIDs = consumerConf.RegistryIDs
}
if cliOpts.overallReference.TracingKey == "" {
cliOpts.overallReference.TracingKey = consumerConf.TracingKey
}
if cliOpts.overallReference.Check == nil {
cliOpts.overallReference.Check = &consumerConf.Check
}
}
// init graceful_shutdown
graceful_shutdown.Init(graceful_shutdown.SetShutdownConfig(cliOpts.Shutdown))
return nil
}
type ClientOption func(*ClientOptions)
func WithClientNoCheck() ClientOption {
return func(opts *ClientOptions) {
opts.Consumer.Check = false
}
}
func WithClientURL(url string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.URL = url
}
}
// todo(DMwangnima): change Filter Option like Cluster and LoadBalance
func WithClientFilter(filter string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Filter = filter
}
}
// todo(DMwangnima): think about a more ideal configuration style
func WithClientRegistryIDs(registryIDs ...string) ClientOption {
return func(opts *ClientOptions) {
if len(registryIDs) > 0 {
opts.Consumer.RegistryIDs = registryIDs
}
}
}
func WithClientRegistry(opts ...registry.Option) ClientOption {
regOpts := registry.NewOptions(opts...)
return func(cliOpts *ClientOptions) {
cliOpts.Registries[regOpts.ID] = regOpts.Registry
}
}
func WithClientShutdown(opts ...graceful_shutdown.Option) ClientOption {
sdOpts := graceful_shutdown.NewOptions(opts...)
return func(cliOpts *ClientOptions) {
cliOpts.Shutdown = sdOpts.Shutdown
}
}
func WithClientTLSOption(opts ...tls.Option) ClientOption {
tlsOpts := tls.NewOptions(opts...)
return func(cliOpts *ClientOptions) {
if cliOpts.TLS == nil {
cliOpts.TLS = new(global.TLSConfig)
}
cliOpts.TLS = tlsOpts.TLSConf
}
}
// ========== Cluster Strategy ==========
func WithClientClusterAvailable() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyAvailable
}
}
func WithClientClusterBroadcast() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyBroadcast
}
}
func WithClientClusterFailBack() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyFailback
}
}
func WithClientClusterFailFast() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyFailfast
}
}
func WithClientClusterFailOver() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyFailover
}
}
func WithClientClusterFailSafe() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyFailsafe
}
}
func WithClientClusterForking() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyForking
}
}
func WithClientClusterZoneAware() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyZoneAware
}
}
func WithClientClusterAdaptiveService() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = constant.ClusterKeyAdaptiveService
}
}
func WithClientClusterStrategy(strategy string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Cluster = strategy
}
}
// Deprecated:use triple.WithKeepAliveInterval()
func WithKeepAliveInterval(keepAliveInterval time.Duration) ClientOption {
return func(_ *ClientOptions) {
panic("use triple.WithKeepAliveInterval()")
}
}
// Deprecated:use triple.WithKeepAliveTimeout()
func WithKeepAliveTimeout(keepAliveTimeout time.Duration) ClientOption {
return func(_ *ClientOptions) {
panic("use triple.WithKeepAliveTimeout()")
}
}
// ========== LoadBalance Strategy ==========
func WithClientLoadBalanceConsistentHashing() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = constant.LoadBalanceKeyConsistentHashing
}
}
func WithClientLoadBalanceLeastActive() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = constant.LoadBalanceKeyLeastActive
}
}
func WithClientLoadBalanceRandom() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = constant.LoadBalanceKeyRandom
}
}
func WithClientLoadBalanceRoundRobin() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = constant.LoadBalanceKeyRoundRobin
}
}
func WithClientLoadBalanceP2C() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = constant.LoadBalanceKeyP2C
}
}
func WithClientLoadBalance(lb string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Loadbalance = lb
}
}
func WithClientRetries(retries int) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Retries = strconv.Itoa(retries)
}
}
// is this needed?
func WithClientGroup(group string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Group = group
}
}
// is this needed?
func WithClientVersion(version string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Version = version
}
}
func WithClientSerializationJSON() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Serialization = constant.JSONSerialization
}
}
func WithClientSerialization(ser string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Serialization = ser
}
}
func WithClientProvidedBy(providedBy string) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.ProvidedBy = providedBy
}
}
// todo(DMwangnima): implement this functionality
// func WithAsync() ClientOption {
// return func(opts *ClientOptions) {
// opts.Consumer.Async = true
// }
// }
func WithClientParams(params map[string]string) ClientOption {
return func(opts *ClientOptions) {
if len(params) <= 0 {
return
}
opts.overallReference.Params = params
}
}
func WithClientParam(k, v string) ClientOption {
return func(opts *ClientOptions) {
if opts.overallReference.Params == nil {
opts.overallReference.Params = make(map[string]string, 8)
}
opts.overallReference.Params[k] = v
}
}
// WithClientRouter appends router configurations to the client options.
// This is a user-facing option for incrementally adding routers.
// It appends to the current router slice instead of replacing it.
func WithClientRouter(routers ...*global.RouterConfig) ClientOption {
return func(opts *ClientOptions) {
if len(routers) > 0 {
opts.Routers = append(opts.Routers, routers...)
}
}
}
// todo(DMwangnima): implement this functionality
// func WithClientGeneric(generic bool) ClientOption {
// return func(opts *ClientOptions) {
// if generic {
// opts.Consumer.Generic = "true"
// } else {
// opts.Consumer.Generic = "false"
// }
// }
// }
func WithClientSticky() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.Sticky = true
}
}
// ========== Protocol to consume ==========
func WithClientProtocolDubbo() ClientOption {
return func(opts *ClientOptions) {
opts.Consumer.Protocol = constant.DubboProtocol
}
}
func WithClientProtocolTriple() ClientOption {
return func(opts *ClientOptions) {
opts.Consumer.Protocol = constant.TriProtocol
}
}
func WithClientProtocolJsonRPC() ClientOption {
return func(opts *ClientOptions) {
opts.Consumer.Protocol = constant.JSONRPCProtocol
}
}
func WithClientProtocol(opts ...protocol.ClientOption) ClientOption {
proOpts := protocol.NewClientOptions(opts...)
return func(srvOpts *ClientOptions) {
if srvOpts.overallReference.ProtocolClientConfig == nil {
srvOpts.overallReference.ProtocolClientConfig = new(global.ClientProtocolConfig)
}
srvOpts.overallReference.ProtocolClientConfig = proOpts.ProtocolClient
}
}
func WithClientRequestTimeout(timeout time.Duration) ClientOption {
return func(opts *ClientOptions) {
opts.Consumer.RequestTimeout = timeout.String()
}
}
func WithClientForceTag() ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.ForceTag = true
}
}
func WithClientMeshProviderPort(port int) ClientOption {
return func(opts *ClientOptions) {
opts.overallReference.MeshProviderPort = port
}
}
func SetClientRegistries(regs map[string]*global.RegistryConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Registries = regs
}
}
func SetClientApplication(application *global.ApplicationConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Application = application
}
}
func SetClientConsumer(consumer *global.ConsumerConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Consumer = consumer
}
}
func SetClientShutdown(shutdown *global.ShutdownConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Shutdown = shutdown
}
}
func SetClientMetrics(metrics *global.MetricsConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Metrics = metrics
}
}
func SetClientOtel(otel *global.OtelConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Otel = otel
}
}
func SetClientTLS(tls *global.TLSConfig) ClientOption {
return func(opts *ClientOptions) {
opts.TLS = tls
}
}
// SetClientProtocols sets the protocols configuration for the client.
// This function is used by the framework to configure protocol settings from global configuration.
// It accepts a map of protocol configurations where the key is the protocol name
// and the value is the corresponding protocol configuration.
func SetClientProtocols(protocols map[string]*global.ProtocolConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Protocols = protocols
}
}
// SetClientRouters sets the routers configuration for the client.
// This is an internal framework function for applying router settings to
// client options.
// End users should not use this function for configuration.
// It replaces the current router slice instead of appending to it.
func SetClientRouters(routers []*global.RouterConfig) ClientOption {
return func(opts *ClientOptions) {
opts.Routers = routers
}
}
// todo: need to be consistent with MethodConfig
type CallOptions struct {
RequestTimeout string
Retries string
}
type CallOption func(*CallOptions)
func newDefaultCallOptions() *CallOptions {
return &CallOptions{}
}
// WithCallRequestTimeout the maximum waiting time for one specific call, only works for 'tri' and 'dubbo' protocol
func WithCallRequestTimeout(timeout time.Duration) CallOption {
return func(opts *CallOptions) {
opts.RequestTimeout = timeout.String()
}
}
// WithCallRetries the maximum retry times on request failure for one specific call, only works for 'tri' and 'dubbo' protocol
func WithCallRetries(retries int) CallOption {
return func(opts *CallOptions) {
opts.Retries = strconv.Itoa(retries)
}
}