github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/balancer/clusterresolver/config.go (about)

     1  /*
     2   *
     3   * Copyright 2021 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package clusterresolver
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/json"
    23  	"fmt"
    24  	"strings"
    25  
    26  	"github.com/hxx258456/ccgo/grpc/balancer/roundrobin"
    27  	internalserviceconfig "github.com/hxx258456/ccgo/grpc/internal/serviceconfig"
    28  	"github.com/hxx258456/ccgo/grpc/serviceconfig"
    29  	"github.com/hxx258456/ccgo/grpc/xds/internal/balancer/ringhash"
    30  )
    31  
    32  // DiscoveryMechanismType is the type of discovery mechanism.
    33  type DiscoveryMechanismType int
    34  
    35  const (
    36  	// DiscoveryMechanismTypeEDS is eds.
    37  	DiscoveryMechanismTypeEDS DiscoveryMechanismType = iota // `json:"EDS"`
    38  	// DiscoveryMechanismTypeLogicalDNS is DNS.
    39  	DiscoveryMechanismTypeLogicalDNS // `json:"LOGICAL_DNS"`
    40  )
    41  
    42  // MarshalJSON marshals a DiscoveryMechanismType to a quoted json string.
    43  //
    44  // This is necessary to handle enum (as strings) from JSON.
    45  //
    46  // Note that this needs to be defined on the type not pointer, otherwise the
    47  // variables of this type will marshal to int not string.
    48  func (t DiscoveryMechanismType) MarshalJSON() ([]byte, error) {
    49  	buffer := bytes.NewBufferString(`"`)
    50  	switch t {
    51  	case DiscoveryMechanismTypeEDS:
    52  		buffer.WriteString("EDS")
    53  	case DiscoveryMechanismTypeLogicalDNS:
    54  		buffer.WriteString("LOGICAL_DNS")
    55  	}
    56  	buffer.WriteString(`"`)
    57  	return buffer.Bytes(), nil
    58  }
    59  
    60  // UnmarshalJSON unmarshals a quoted json string to the DiscoveryMechanismType.
    61  func (t *DiscoveryMechanismType) UnmarshalJSON(b []byte) error {
    62  	var s string
    63  	err := json.Unmarshal(b, &s)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	switch s {
    68  	case "EDS":
    69  		*t = DiscoveryMechanismTypeEDS
    70  	case "LOGICAL_DNS":
    71  		*t = DiscoveryMechanismTypeLogicalDNS
    72  	default:
    73  		return fmt.Errorf("unable to unmarshal string %q to type DiscoveryMechanismType", s)
    74  	}
    75  	return nil
    76  }
    77  
    78  // DiscoveryMechanism is the discovery mechanism, can be either EDS or DNS.
    79  //
    80  // For DNS, the ClientConn target will be used for name resolution.
    81  //
    82  // For EDS, if EDSServiceName is not empty, it will be used for watching. If
    83  // EDSServiceName is empty, Cluster will be used.
    84  type DiscoveryMechanism struct {
    85  	// Cluster is the cluster name.
    86  	Cluster string `json:"cluster,omitempty"`
    87  	// LoadReportingServerName is the LRS server to send load reports to. If
    88  	// not present, load reporting will be disabled. If set to the empty string,
    89  	// load reporting will be sent to the same server that we obtained CDS data
    90  	// from.
    91  	LoadReportingServerName *string `json:"lrsLoadReportingServerName,omitempty"`
    92  	// MaxConcurrentRequests is the maximum number of outstanding requests can
    93  	// be made to the upstream cluster. Default is 1024.
    94  	MaxConcurrentRequests *uint32 `json:"maxConcurrentRequests,omitempty"`
    95  	// Type is the discovery mechanism type.
    96  	Type DiscoveryMechanismType `json:"type,omitempty"`
    97  	// EDSServiceName is the EDS service name, as returned in CDS. May be unset
    98  	// if not specified in CDS. For type EDS only.
    99  	//
   100  	// This is used for EDS watch if set. If unset, Cluster is used for EDS
   101  	// watch.
   102  	EDSServiceName string `json:"edsServiceName,omitempty"`
   103  	// DNSHostname is the DNS name to resolve in "host:port" form. For type
   104  	// LOGICAL_DNS only.
   105  	DNSHostname string `json:"dnsHostname,omitempty"`
   106  }
   107  
   108  // Equal returns whether the DiscoveryMechanism is the same with the parameter.
   109  func (dm DiscoveryMechanism) Equal(b DiscoveryMechanism) bool {
   110  	switch {
   111  	case dm.Cluster != b.Cluster:
   112  		return false
   113  	case !equalStringP(dm.LoadReportingServerName, b.LoadReportingServerName):
   114  		return false
   115  	case !equalUint32P(dm.MaxConcurrentRequests, b.MaxConcurrentRequests):
   116  		return false
   117  	case dm.Type != b.Type:
   118  		return false
   119  	case dm.EDSServiceName != b.EDSServiceName:
   120  		return false
   121  	case dm.DNSHostname != b.DNSHostname:
   122  		return false
   123  	}
   124  	return true
   125  }
   126  
   127  func equalStringP(a, b *string) bool {
   128  	if a == nil && b == nil {
   129  		return true
   130  	}
   131  	if a == nil || b == nil {
   132  		return false
   133  	}
   134  	return *a == *b
   135  }
   136  
   137  func equalUint32P(a, b *uint32) bool {
   138  	if a == nil && b == nil {
   139  		return true
   140  	}
   141  	if a == nil || b == nil {
   142  		return false
   143  	}
   144  	return *a == *b
   145  }
   146  
   147  // LBConfig is the config for cluster resolver balancer.
   148  type LBConfig struct {
   149  	serviceconfig.LoadBalancingConfig `json:"-"`
   150  	// DiscoveryMechanisms is an ordered list of discovery mechanisms.
   151  	//
   152  	// Must have at least one element. Results from each discovery mechanism are
   153  	// concatenated together in successive priorities.
   154  	DiscoveryMechanisms []DiscoveryMechanism `json:"discoveryMechanisms,omitempty"`
   155  
   156  	// XDSLBPolicy specifies the policy for locality picking and endpoint picking.
   157  	//
   158  	// Note that it's not normal balancing policy, and it can only be either
   159  	// ROUND_ROBIN or RING_HASH.
   160  	//
   161  	// For ROUND_ROBIN, the policy name will be "ROUND_ROBIN", and the config
   162  	// will be empty. This sets the locality-picking policy to weighted_target
   163  	// and the endpoint-picking policy to round_robin.
   164  	//
   165  	// For RING_HASH, the policy name will be "RING_HASH", and the config will
   166  	// be lb config for the ring_hash_experimental LB Policy. ring_hash policy
   167  	// is responsible for both locality picking and endpoint picking.
   168  	XDSLBPolicy *internalserviceconfig.BalancerConfig `json:"xdsLbPolicy,omitempty"`
   169  }
   170  
   171  const (
   172  	rrName = roundrobin.Name
   173  	rhName = ringhash.Name
   174  )
   175  
   176  func parseConfig(c json.RawMessage) (*LBConfig, error) {
   177  	var cfg LBConfig
   178  	if err := json.Unmarshal(c, &cfg); err != nil {
   179  		return nil, err
   180  	}
   181  	if lbp := cfg.XDSLBPolicy; lbp != nil && !strings.EqualFold(lbp.Name, rrName) && !strings.EqualFold(lbp.Name, rhName) {
   182  		return nil, fmt.Errorf("unsupported child policy with name %q, not one of {%q,%q}", lbp.Name, rrName, rhName)
   183  	}
   184  	return &cfg, nil
   185  }