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 }