xds: replace eds proto message with xdsclient defined struct in eds balancer (#3174)
The xds client will parse the EDS response, and give the parse result to eds balancer, so the balancer doesn't need to deal with proto directly. Also moved `ClusterLoadAssignmentBuilder` to another pacakge to be shared by tests in different packages.
This commit is contained in:
@ -20,16 +20,10 @@ package edsbalancer
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
|
||||||
corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
|
||||||
endpointpb "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
|
|
||||||
typepb "github.com/envoyproxy/go-control-plane/envoy/type"
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/balancer/roundrobin"
|
"google.golang.org/grpc/balancer/roundrobin"
|
||||||
"google.golang.org/grpc/balancer/weightedroundrobin"
|
"google.golang.org/grpc/balancer/weightedroundrobin"
|
||||||
@ -40,6 +34,7 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/grpc/xds/internal"
|
"google.golang.org/grpc/xds/internal"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make this a environment variable?
|
// TODO: make this a environment variable?
|
||||||
@ -154,26 +149,17 @@ func (xdsB *EDSBalancer) HandleChildPolicy(name string, config json.RawMessage)
|
|||||||
|
|
||||||
// updateDrops compares new drop policies with the old. If they are different,
|
// updateDrops compares new drop policies with the old. If they are different,
|
||||||
// it updates the drop policies and send ClientConn an updated picker.
|
// it updates the drop policies and send ClientConn an updated picker.
|
||||||
func (xdsB *EDSBalancer) updateDrops(dropPolicies []*xdspb.ClusterLoadAssignment_Policy_DropOverload) {
|
func (xdsB *EDSBalancer) updateDrops(dropPolicies []xdsclient.OverloadDropConfig) {
|
||||||
var (
|
var (
|
||||||
newDrops []*dropper
|
newDrops []*dropper
|
||||||
dropsChanged bool
|
dropsChanged bool
|
||||||
)
|
)
|
||||||
for i, dropPolicy := range dropPolicies {
|
for i, dropPolicy := range dropPolicies {
|
||||||
percentage := dropPolicy.GetDropPercentage()
|
|
||||||
var (
|
var (
|
||||||
numerator = percentage.GetNumerator()
|
numerator = dropPolicy.Numerator
|
||||||
denominator uint32
|
denominator = dropPolicy.Denominator
|
||||||
)
|
)
|
||||||
switch percentage.GetDenominator() {
|
newDrops = append(newDrops, newDropper(numerator, denominator, dropPolicy.Category))
|
||||||
case typepb.FractionalPercent_HUNDRED:
|
|
||||||
denominator = 100
|
|
||||||
case typepb.FractionalPercent_TEN_THOUSAND:
|
|
||||||
denominator = 10000
|
|
||||||
case typepb.FractionalPercent_MILLION:
|
|
||||||
denominator = 1000000
|
|
||||||
}
|
|
||||||
newDrops = append(newDrops, newDropper(numerator, denominator, dropPolicy.GetCategory()))
|
|
||||||
|
|
||||||
// The following reading xdsB.drops doesn't need mutex because it can only
|
// The following reading xdsB.drops doesn't need mutex because it can only
|
||||||
// be updated by the code following.
|
// be updated by the code following.
|
||||||
@ -203,7 +189,7 @@ func (xdsB *EDSBalancer) updateDrops(dropPolicies []*xdspb.ClusterLoadAssignment
|
|||||||
// SubConns. It also handles drops.
|
// SubConns. It also handles drops.
|
||||||
//
|
//
|
||||||
// HandleChildPolicy and HandleEDSResponse must be called by the same goroutine.
|
// HandleChildPolicy and HandleEDSResponse must be called by the same goroutine.
|
||||||
func (xdsB *EDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment) {
|
func (xdsB *EDSBalancer) HandleEDSResponse(edsResp *xdsclient.EDSUpdate) {
|
||||||
// TODO: Unhandled fields from EDS response:
|
// TODO: Unhandled fields from EDS response:
|
||||||
// - edsResp.GetPolicy().GetOverprovisioningFactor()
|
// - edsResp.GetPolicy().GetOverprovisioningFactor()
|
||||||
// - locality.GetPriority()
|
// - locality.GetPriority()
|
||||||
@ -213,7 +199,7 @@ func (xdsB *EDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment)
|
|||||||
// - socketAddress.GetNamedPort(), socketAddress.GetResolverName()
|
// - socketAddress.GetNamedPort(), socketAddress.GetResolverName()
|
||||||
// - resolve endpoint's name with another resolver
|
// - resolve endpoint's name with another resolver
|
||||||
|
|
||||||
xdsB.updateDrops(edsResp.GetPolicy().GetDropOverloads())
|
xdsB.updateDrops(edsResp.Drops)
|
||||||
|
|
||||||
// Filter out all localities with weight 0.
|
// Filter out all localities with weight 0.
|
||||||
//
|
//
|
||||||
@ -224,12 +210,12 @@ func (xdsB *EDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment)
|
|||||||
//
|
//
|
||||||
// In the future, we should look at the config in CDS response and decide
|
// In the future, we should look at the config in CDS response and decide
|
||||||
// whether locality weight matters.
|
// whether locality weight matters.
|
||||||
newLocalitiesWithPriority := make(map[priorityType][]*endpointpb.LocalityLbEndpoints)
|
newLocalitiesWithPriority := make(map[priorityType][]xdsclient.Locality)
|
||||||
for _, locality := range edsResp.Endpoints {
|
for _, locality := range edsResp.Localities {
|
||||||
if locality.GetLoadBalancingWeight().GetValue() == 0 {
|
if locality.Weight == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
priority := newPriorityType(locality.GetPriority())
|
priority := newPriorityType(locality.Priority)
|
||||||
newLocalitiesWithPriority[priority] = append(newLocalitiesWithPriority[priority], locality)
|
newLocalitiesWithPriority[priority] = append(newLocalitiesWithPriority[priority], locality)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +267,7 @@ func (xdsB *EDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (xdsB *EDSBalancer) handleEDSResponsePerPriority(bgwc *balancerGroupWithConfig, newLocalities []*endpointpb.LocalityLbEndpoints) {
|
func (xdsB *EDSBalancer) handleEDSResponsePerPriority(bgwc *balancerGroupWithConfig, newLocalities []xdsclient.Locality) {
|
||||||
// newLocalitiesSet contains all names of localities in the new EDS response
|
// newLocalitiesSet contains all names of localities in the new EDS response
|
||||||
// for the same priority. It's used to delete localities that are removed in
|
// for the same priority. It's used to delete localities that are removed in
|
||||||
// the new EDS response.
|
// the new EDS response.
|
||||||
@ -289,37 +275,26 @@ func (xdsB *EDSBalancer) handleEDSResponsePerPriority(bgwc *balancerGroupWithCon
|
|||||||
for _, locality := range newLocalities {
|
for _, locality := range newLocalities {
|
||||||
// One balancer for each locality.
|
// One balancer for each locality.
|
||||||
|
|
||||||
l := locality.GetLocality()
|
lid := locality.ID
|
||||||
if l == nil {
|
|
||||||
grpclog.Warningf("xds: received LocalityLbEndpoints with <nil> Locality")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
lid := internal.Locality{
|
|
||||||
Region: l.Region,
|
|
||||||
Zone: l.Zone,
|
|
||||||
SubZone: l.SubZone,
|
|
||||||
}
|
|
||||||
newLocalitiesSet[lid] = struct{}{}
|
newLocalitiesSet[lid] = struct{}{}
|
||||||
|
|
||||||
newWeight := locality.GetLoadBalancingWeight().GetValue()
|
newWeight := locality.Weight
|
||||||
var newAddrs []resolver.Address
|
var newAddrs []resolver.Address
|
||||||
for _, lbEndpoint := range locality.GetLbEndpoints() {
|
for _, lbEndpoint := range locality.Endpoints {
|
||||||
// Filter out all "unhealthy" endpoints (unknown and
|
// Filter out all "unhealthy" endpoints (unknown and
|
||||||
// healthy are both considered to be healthy:
|
// healthy are both considered to be healthy:
|
||||||
// https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/core/health_check.proto#envoy-api-enum-core-healthstatus).
|
// https://www.envoyproxy.io/docs/envoy/latest/api-v2/api/v2/core/health_check.proto#envoy-api-enum-core-healthstatus).
|
||||||
if lbEndpoint.GetHealthStatus() != corepb.HealthStatus_HEALTHY &&
|
if lbEndpoint.HealthStatus != xdsclient.EndpointHealthStatusHealthy &&
|
||||||
lbEndpoint.GetHealthStatus() != corepb.HealthStatus_UNKNOWN {
|
lbEndpoint.HealthStatus != xdsclient.EndpointHealthStatusUnknown {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
socketAddress := lbEndpoint.GetEndpoint().GetAddress().GetSocketAddress()
|
|
||||||
address := resolver.Address{
|
address := resolver.Address{
|
||||||
Addr: net.JoinHostPort(socketAddress.GetAddress(), strconv.Itoa(int(socketAddress.GetPortValue()))),
|
Addr: lbEndpoint.Address,
|
||||||
}
|
}
|
||||||
if xdsB.subBalancerBuilder.Name() == weightedroundrobin.Name &&
|
if xdsB.subBalancerBuilder.Name() == weightedroundrobin.Name && lbEndpoint.Weight != 0 {
|
||||||
lbEndpoint.GetLoadBalancingWeight().GetValue() != 0 {
|
|
||||||
address.Metadata = &weightedroundrobin.AddrInfo{
|
address.Metadata = &weightedroundrobin.AddrInfo{
|
||||||
Weight: lbEndpoint.GetLoadBalancingWeight().GetValue(),
|
Weight: lbEndpoint.Weight,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newAddrs = append(newAddrs, address)
|
newAddrs = append(newAddrs, address)
|
||||||
|
@ -19,24 +19,19 @@ package edsbalancer
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
|
||||||
corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
||||||
endpointpb "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
|
|
||||||
typepb "github.com/envoyproxy/go-control-plane/envoy/type"
|
|
||||||
typespb "github.com/golang/protobuf/ptypes/wrappers"
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/balancer/roundrobin"
|
"google.golang.org/grpc/balancer/roundrobin"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/xds/internal"
|
"google.golang.org/grpc/xds/internal"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -51,81 +46,6 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type clusterLoadAssignmentBuilder struct {
|
|
||||||
v *xdspb.ClusterLoadAssignment
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClusterLoadAssignmentBuilder(clusterName string, dropPercents []uint32) *clusterLoadAssignmentBuilder {
|
|
||||||
var drops []*xdspb.ClusterLoadAssignment_Policy_DropOverload
|
|
||||||
for i, d := range dropPercents {
|
|
||||||
drops = append(drops, &xdspb.ClusterLoadAssignment_Policy_DropOverload{
|
|
||||||
Category: fmt.Sprintf("test-drop-%d", i),
|
|
||||||
DropPercentage: &typepb.FractionalPercent{
|
|
||||||
Numerator: d,
|
|
||||||
Denominator: typepb.FractionalPercent_HUNDRED,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &clusterLoadAssignmentBuilder{
|
|
||||||
v: &xdspb.ClusterLoadAssignment{
|
|
||||||
ClusterName: clusterName,
|
|
||||||
Policy: &xdspb.ClusterLoadAssignment_Policy{
|
|
||||||
DropOverloads: drops,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type addLocalityOptions struct {
|
|
||||||
health []corepb.HealthStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
func (clab *clusterLoadAssignmentBuilder) addLocality(subzone string, weight uint32, priority uint32, addrsWithPort []string, opts *addLocalityOptions) {
|
|
||||||
var lbEndPoints []*endpointpb.LbEndpoint
|
|
||||||
for i, a := range addrsWithPort {
|
|
||||||
host, portStr, err := net.SplitHostPort(a)
|
|
||||||
if err != nil {
|
|
||||||
panic("failed to split " + a)
|
|
||||||
}
|
|
||||||
port, err := strconv.Atoi(portStr)
|
|
||||||
if err != nil {
|
|
||||||
panic("failed to atoi " + portStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
lbe := &endpointpb.LbEndpoint{
|
|
||||||
HostIdentifier: &endpointpb.LbEndpoint_Endpoint{
|
|
||||||
Endpoint: &endpointpb.Endpoint{
|
|
||||||
Address: &corepb.Address{
|
|
||||||
Address: &corepb.Address_SocketAddress{
|
|
||||||
SocketAddress: &corepb.SocketAddress{
|
|
||||||
Protocol: corepb.SocketAddress_TCP,
|
|
||||||
Address: host,
|
|
||||||
PortSpecifier: &corepb.SocketAddress_PortValue{
|
|
||||||
PortValue: uint32(port)}}}}}},
|
|
||||||
}
|
|
||||||
if opts != nil && i < len(opts.health) {
|
|
||||||
lbe.HealthStatus = opts.health[i]
|
|
||||||
}
|
|
||||||
lbEndPoints = append(lbEndPoints, lbe)
|
|
||||||
}
|
|
||||||
|
|
||||||
clab.v.Endpoints = append(clab.v.Endpoints, &endpointpb.LocalityLbEndpoints{
|
|
||||||
Locality: &corepb.Locality{
|
|
||||||
Region: "",
|
|
||||||
Zone: "",
|
|
||||||
SubZone: subzone,
|
|
||||||
},
|
|
||||||
LbEndpoints: lbEndPoints,
|
|
||||||
LoadBalancingWeight: &typespb.UInt32Value{Value: weight},
|
|
||||||
Priority: priority,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (clab *clusterLoadAssignmentBuilder) build() *xdspb.ClusterLoadAssignment {
|
|
||||||
return clab.v
|
|
||||||
}
|
|
||||||
|
|
||||||
// One locality
|
// One locality
|
||||||
// - add backend
|
// - add backend
|
||||||
// - remove backend
|
// - remove backend
|
||||||
@ -136,9 +56,9 @@ func TestEDS_OneLocality(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// One locality with one backend.
|
// One locality with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
sc1 := <-cc.newSubConnCh
|
sc1 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
||||||
@ -154,9 +74,9 @@ func TestEDS_OneLocality(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The same locality, add one more backend.
|
// The same locality, add one more backend.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:2], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:2], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
sc2 := <-cc.newSubConnCh
|
sc2 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
||||||
@ -173,9 +93,9 @@ func TestEDS_OneLocality(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The same locality, delete first backend.
|
// The same locality, delete first backend.
|
||||||
clab3 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab3 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab3.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[1:2], nil)
|
clab3.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab3.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab3.Build()))
|
||||||
|
|
||||||
scToRemove := <-cc.removeSubConnCh
|
scToRemove := <-cc.removeSubConnCh
|
||||||
if !reflect.DeepEqual(scToRemove, sc1) {
|
if !reflect.DeepEqual(scToRemove, sc1) {
|
||||||
@ -193,9 +113,9 @@ func TestEDS_OneLocality(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The same locality, replace backend.
|
// The same locality, replace backend.
|
||||||
clab4 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab4 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab4.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
clab4.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab4.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab4.Build()))
|
||||||
|
|
||||||
sc3 := <-cc.newSubConnCh
|
sc3 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc3, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc3, connectivity.Connecting)
|
||||||
@ -216,9 +136,9 @@ func TestEDS_OneLocality(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The same locality, different drop rate, dropping 50%.
|
// The same locality, different drop rate, dropping 50%.
|
||||||
clab5 := newClusterLoadAssignmentBuilder(testClusterNames[0], []uint32{50})
|
clab5 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], []uint32{50})
|
||||||
clab5.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
clab5.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab5.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab5.Build()))
|
||||||
|
|
||||||
// Picks with drops.
|
// Picks with drops.
|
||||||
p5 := <-cc.newPickerCh
|
p5 := <-cc.newPickerCh
|
||||||
@ -245,9 +165,9 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, each with one backend.
|
// Two localities, each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
sc1 := <-cc.newSubConnCh
|
sc1 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
||||||
edsb.HandleSubConnStateChange(sc1, connectivity.Ready)
|
edsb.HandleSubConnStateChange(sc1, connectivity.Ready)
|
||||||
@ -255,8 +175,8 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
// Add the second locality later to make sure sc2 belongs to the second
|
// Add the second locality later to make sure sc2 belongs to the second
|
||||||
// locality. Otherwise the test is flaky because of a map is used in EDS to
|
// locality. Otherwise the test is flaky because of a map is used in EDS to
|
||||||
// keep localities.
|
// keep localities.
|
||||||
clab1.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
sc2 := <-cc.newSubConnCh
|
sc2 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
||||||
edsb.HandleSubConnStateChange(sc2, connectivity.Ready)
|
edsb.HandleSubConnStateChange(sc2, connectivity.Ready)
|
||||||
@ -272,11 +192,11 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add another locality, with one backend.
|
// Add another locality, with one backend.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab2.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab2.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
clab2.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
clab2.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
sc3 := <-cc.newSubConnCh
|
sc3 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc3, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc3, connectivity.Connecting)
|
||||||
@ -293,10 +213,10 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove first locality.
|
// Remove first locality.
|
||||||
clab3 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab3 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab3.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab3.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
clab3.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
clab3.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab3.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab3.Build()))
|
||||||
|
|
||||||
scToRemove := <-cc.removeSubConnCh
|
scToRemove := <-cc.removeSubConnCh
|
||||||
if !reflect.DeepEqual(scToRemove, sc1) {
|
if !reflect.DeepEqual(scToRemove, sc1) {
|
||||||
@ -315,10 +235,10 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a backend to the last locality.
|
// Add a backend to the last locality.
|
||||||
clab4 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab4 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab4.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab4.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
clab4.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
clab4.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
||||||
edsb.HandleEDSResponse(clab4.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab4.Build()))
|
||||||
|
|
||||||
sc4 := <-cc.newSubConnCh
|
sc4 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc4, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc4, connectivity.Connecting)
|
||||||
@ -338,10 +258,10 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change weight of the locality[1].
|
// Change weight of the locality[1].
|
||||||
clab5 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab5 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab5.addLocality(testSubZones[1], 2, 0, testEndpointAddrs[1:2], nil)
|
clab5.AddLocality(testSubZones[1], 2, 0, testEndpointAddrs[1:2], nil)
|
||||||
clab5.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
clab5.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
||||||
edsb.HandleEDSResponse(clab5.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab5.Build()))
|
||||||
|
|
||||||
// Test pick with two subconns different locality weight.
|
// Test pick with two subconns different locality weight.
|
||||||
p5 := <-cc.newPickerCh
|
p5 := <-cc.newPickerCh
|
||||||
@ -357,10 +277,10 @@ func TestEDS_TwoLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change weight of the locality[1] to 0, it should never be picked.
|
// Change weight of the locality[1] to 0, it should never be picked.
|
||||||
clab6 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab6 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab6.addLocality(testSubZones[1], 0, 0, testEndpointAddrs[1:2], nil)
|
clab6.AddLocality(testSubZones[1], 0, 0, testEndpointAddrs[1:2], nil)
|
||||||
clab6.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
clab6.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:4], nil)
|
||||||
edsb.HandleEDSResponse(clab6.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab6.Build()))
|
||||||
|
|
||||||
// Changing weight of locality[1] to 0 caused it to be removed. It's subconn
|
// Changing weight of locality[1] to 0 caused it to be removed. It's subconn
|
||||||
// should also be removed.
|
// should also be removed.
|
||||||
@ -393,9 +313,9 @@ func TestEDS_EndpointsHealth(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, each 3 backend, one Healthy, one Unhealthy, one Unknown.
|
// Two localities, each 3 backend, one Healthy, one Unhealthy, one Unknown.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:6], &addLocalityOptions{
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:6], &xdsclient.AddLocalityOptions{
|
||||||
health: []corepb.HealthStatus{
|
Health: []corepb.HealthStatus{
|
||||||
corepb.HealthStatus_HEALTHY,
|
corepb.HealthStatus_HEALTHY,
|
||||||
corepb.HealthStatus_UNHEALTHY,
|
corepb.HealthStatus_UNHEALTHY,
|
||||||
corepb.HealthStatus_UNKNOWN,
|
corepb.HealthStatus_UNKNOWN,
|
||||||
@ -404,8 +324,8 @@ func TestEDS_EndpointsHealth(t *testing.T) {
|
|||||||
corepb.HealthStatus_DEGRADED,
|
corepb.HealthStatus_DEGRADED,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
clab1.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[6:12], &addLocalityOptions{
|
clab1.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[6:12], &xdsclient.AddLocalityOptions{
|
||||||
health: []corepb.HealthStatus{
|
Health: []corepb.HealthStatus{
|
||||||
corepb.HealthStatus_HEALTHY,
|
corepb.HealthStatus_HEALTHY,
|
||||||
corepb.HealthStatus_UNHEALTHY,
|
corepb.HealthStatus_UNHEALTHY,
|
||||||
corepb.HealthStatus_UNKNOWN,
|
corepb.HealthStatus_UNKNOWN,
|
||||||
@ -414,7 +334,7 @@ func TestEDS_EndpointsHealth(t *testing.T) {
|
|||||||
corepb.HealthStatus_DEGRADED,
|
corepb.HealthStatus_DEGRADED,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
var (
|
var (
|
||||||
readySCs []balancer.SubConn
|
readySCs []balancer.SubConn
|
||||||
@ -527,10 +447,10 @@ func TestEDS_UpdateSubBalancerName(t *testing.T) {
|
|||||||
edsb.HandleChildPolicy("test-const-balancer", nil)
|
edsb.HandleChildPolicy("test-const-balancer", nil)
|
||||||
|
|
||||||
// Two localities, each with one backend.
|
// Two localities, each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
sc := <-cc.newSubConnCh
|
sc := <-cc.newSubConnCh
|
||||||
@ -691,9 +611,9 @@ func TestEDS_LoadReport(t *testing.T) {
|
|||||||
backendToBalancerID := make(map[balancer.SubConn]internal.Locality)
|
backendToBalancerID := make(map[balancer.SubConn]internal.Locality)
|
||||||
|
|
||||||
// Two localities, each with one backend.
|
// Two localities, each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
sc1 := <-cc.newSubConnCh
|
sc1 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc1, connectivity.Connecting)
|
||||||
edsb.HandleSubConnStateChange(sc1, connectivity.Ready)
|
edsb.HandleSubConnStateChange(sc1, connectivity.Ready)
|
||||||
@ -704,8 +624,8 @@ func TestEDS_LoadReport(t *testing.T) {
|
|||||||
// Add the second locality later to make sure sc2 belongs to the second
|
// Add the second locality later to make sure sc2 belongs to the second
|
||||||
// locality. Otherwise the test is flaky because of a map is used in EDS to
|
// locality. Otherwise the test is flaky because of a map is used in EDS to
|
||||||
// keep localities.
|
// keep localities.
|
||||||
clab1.addLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
sc2 := <-cc.newSubConnCh
|
sc2 := <-cc.newSubConnCh
|
||||||
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
edsb.HandleSubConnStateChange(sc2, connectivity.Connecting)
|
||||||
edsb.HandleSubConnStateChange(sc2, connectivity.Ready)
|
edsb.HandleSubConnStateChange(sc2, connectivity.Ready)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// When a high priority is ready, adding/removing lower locality doesn't cause
|
// When a high priority is ready, adding/removing lower locality doesn't cause
|
||||||
@ -36,10 +37,10 @@ func TestEDSPriority_HighPriorityReady(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with priorities [0, 1], each with one backend.
|
// Two localities, with priorities [0, 1], each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs1 := <-cc.newSubConnAddrsCh
|
addrs1 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs1[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs1[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -63,11 +64,11 @@ func TestEDSPriority_HighPriorityReady(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add p2, it shouldn't cause any udpates.
|
// Add p2, it shouldn't cause any udpates.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab2.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab2.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
clab2.addLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
clab2.AddLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-cc.newPickerCh:
|
case <-cc.newPickerCh:
|
||||||
@ -80,10 +81,10 @@ func TestEDSPriority_HighPriorityReady(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove p2, no updates.
|
// Remove p2, no updates.
|
||||||
clab3 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab3 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab3.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab3.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab3.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab3.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab3.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab3.Build()))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-cc.newPickerCh:
|
case <-cc.newPickerCh:
|
||||||
@ -105,10 +106,10 @@ func TestEDSPriority_SwitchPriority(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with priorities [0, 1], each with one backend.
|
// Two localities, with priorities [0, 1], each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -151,11 +152,11 @@ func TestEDSPriority_SwitchPriority(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add p2, it shouldn't cause any udpates.
|
// Add p2, it shouldn't cause any udpates.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab2.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab2.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
clab2.addLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
clab2.AddLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-cc.newPickerCh:
|
case <-cc.newPickerCh:
|
||||||
@ -187,10 +188,10 @@ func TestEDSPriority_SwitchPriority(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove 2, use 1.
|
// Remove 2, use 1.
|
||||||
clab3 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab3 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab3.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab3.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab3.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab3.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab3.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab3.Build()))
|
||||||
|
|
||||||
// p2 SubConns are removed.
|
// p2 SubConns are removed.
|
||||||
scToRemove := <-cc.removeSubConnCh
|
scToRemove := <-cc.removeSubConnCh
|
||||||
@ -215,10 +216,10 @@ func TestEDSPriority_HigherDownWhileAddingLower(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with different priorities, each with one backend.
|
// Two localities, with different priorities, each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -245,11 +246,11 @@ func TestEDSPriority_HigherDownWhileAddingLower(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add p2, it should create a new SubConn.
|
// Add p2, it should create a new SubConn.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab2.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab2.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
clab2.addLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
clab2.AddLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
addrs2 := <-cc.newSubConnAddrsCh
|
addrs2 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs2[0].Addr, testEndpointAddrs[2]; got != want {
|
if got, want := addrs2[0].Addr, testEndpointAddrs[2]; got != want {
|
||||||
@ -279,11 +280,11 @@ func TestEDSPriority_HigherReadyCloseAllLower(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with priorities [0,1,2], each with one backend.
|
// Two localities, with priorities [0,1,2], each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
clab1.addLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
clab1.AddLocality(testSubZones[2], 1, 2, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -358,10 +359,10 @@ func TestEDSPriority_InitTimeout(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with different priorities, each with one backend.
|
// Two localities, with different priorities, each with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -407,10 +408,10 @@ func TestEDSPriority_MultipleLocalities(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with different priorities, each with one backend.
|
// Two localities, with different priorities, each with one backend.
|
||||||
clab0 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab0 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab0.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab0.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab0.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab0.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab0.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab0.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -472,12 +473,12 @@ func TestEDSPriority_MultipleLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add two localities, with two priorities, with one backend.
|
// Add two localities, with two priorities, with one backend.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab1.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab1.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab1.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
clab1.addLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
clab1.AddLocality(testSubZones[2], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
clab1.addLocality(testSubZones[3], 1, 1, testEndpointAddrs[3:4], nil)
|
clab1.AddLocality(testSubZones[3], 1, 1, testEndpointAddrs[3:4], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
addrs2 := <-cc.newSubConnAddrsCh
|
addrs2 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs2[0].Addr, testEndpointAddrs[2]; got != want {
|
if got, want := addrs2[0].Addr, testEndpointAddrs[2]; got != want {
|
||||||
@ -534,10 +535,10 @@ func TestEDSPriority_RemovesAllLocalities(t *testing.T) {
|
|||||||
edsb := NewXDSBalancer(cc, nil)
|
edsb := NewXDSBalancer(cc, nil)
|
||||||
|
|
||||||
// Two localities, with different priorities, each with one backend.
|
// Two localities, with different priorities, each with one backend.
|
||||||
clab0 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab0 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab0.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
clab0.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil)
|
||||||
clab0.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
clab0.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[1:2], nil)
|
||||||
edsb.HandleEDSResponse(clab0.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab0.Build()))
|
||||||
|
|
||||||
addrs0 := <-cc.newSubConnAddrsCh
|
addrs0 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want {
|
||||||
@ -559,8 +560,8 @@ func TestEDSPriority_RemovesAllLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove all priorities.
|
// Remove all priorities.
|
||||||
clab1 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab1 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
edsb.HandleEDSResponse(clab1.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab1.Build()))
|
||||||
|
|
||||||
// p0 subconn should be removed.
|
// p0 subconn should be removed.
|
||||||
scToRemove := <-cc.removeSubConnCh
|
scToRemove := <-cc.removeSubConnCh
|
||||||
@ -577,10 +578,10 @@ func TestEDSPriority_RemovesAllLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Re-add two localities, with previous priorities, but different backends.
|
// Re-add two localities, with previous priorities, but different backends.
|
||||||
clab2 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab2 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab2.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
clab2.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
clab2.addLocality(testSubZones[1], 1, 1, testEndpointAddrs[3:4], nil)
|
clab2.AddLocality(testSubZones[1], 1, 1, testEndpointAddrs[3:4], nil)
|
||||||
edsb.HandleEDSResponse(clab2.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab2.Build()))
|
||||||
|
|
||||||
addrs01 := <-cc.newSubConnAddrsCh
|
addrs01 := <-cc.newSubConnAddrsCh
|
||||||
if got, want := addrs01[0].Addr, testEndpointAddrs[2]; got != want {
|
if got, want := addrs01[0].Addr, testEndpointAddrs[2]; got != want {
|
||||||
@ -612,9 +613,9 @@ func TestEDSPriority_RemovesAllLocalities(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove p1 from EDS, to fallback to p0.
|
// Remove p1 from EDS, to fallback to p0.
|
||||||
clab3 := newClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
clab3 := xdsclient.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil)
|
||||||
clab3.addLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
clab3.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[2:3], nil)
|
||||||
edsb.HandleEDSResponse(clab3.build())
|
edsb.HandleEDSResponse(xdsclient.ParseEDSRespProtoForTesting(clab3.Build()))
|
||||||
|
|
||||||
// p1 subconn should be removed.
|
// p1 subconn should be removed.
|
||||||
scToRemove1 := <-cc.removeSubConnCh
|
scToRemove1 := <-cc.removeSubConnCh
|
||||||
|
@ -27,8 +27,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
@ -36,6 +34,7 @@ import (
|
|||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/edsbalancer"
|
"google.golang.org/grpc/xds/internal/balancer/edsbalancer"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -101,7 +100,7 @@ func (b *xdsBalancerBuilder) ParseConfig(c json.RawMessage) (serviceconfig.LoadB
|
|||||||
// It's implemented by the real eds balancer and a fake testing eds balancer.
|
// It's implemented by the real eds balancer and a fake testing eds balancer.
|
||||||
type edsBalancerInterface interface {
|
type edsBalancerInterface interface {
|
||||||
// HandleEDSResponse passes the received EDS message from traffic director to eds balancer.
|
// HandleEDSResponse passes the received EDS message from traffic director to eds balancer.
|
||||||
HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment)
|
HandleEDSResponse(edsResp *xdsclient.EDSUpdate)
|
||||||
// HandleChildPolicy updates the eds balancer the intra-cluster load balancing policy to use.
|
// HandleChildPolicy updates the eds balancer the intra-cluster load balancing policy to use.
|
||||||
HandleChildPolicy(name string, config json.RawMessage)
|
HandleChildPolicy(name string, config json.RawMessage)
|
||||||
// HandleSubConnStateChange handles state change for SubConn.
|
// HandleSubConnStateChange handles state change for SubConn.
|
||||||
@ -158,7 +157,7 @@ func (x *xdsBalancer) startNewXDSClient(u *XDSConfig) {
|
|||||||
var haveGotADS bool
|
var haveGotADS bool
|
||||||
|
|
||||||
// set up callbacks for the xds client.
|
// set up callbacks for the xds client.
|
||||||
newADS := func(ctx context.Context, resp proto.Message) error {
|
newADS := func(ctx context.Context, resp *xdsclient.EDSUpdate) error {
|
||||||
if !haveGotADS {
|
if !haveGotADS {
|
||||||
if prevClient != nil {
|
if prevClient != nil {
|
||||||
prevClient.close()
|
prevClient.close()
|
||||||
@ -410,21 +409,12 @@ func (x *xdsBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
|
|||||||
|
|
||||||
type edsResp struct {
|
type edsResp struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
resp *xdspb.ClusterLoadAssignment
|
resp *xdsclient.EDSUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *xdsBalancer) newADSResponse(ctx context.Context, resp proto.Message) error {
|
func (x *xdsBalancer) newADSResponse(ctx context.Context, resp *xdsclient.EDSUpdate) error {
|
||||||
var update interface{}
|
|
||||||
switch u := resp.(type) {
|
|
||||||
case *xdspb.ClusterLoadAssignment:
|
|
||||||
// nothing to check
|
|
||||||
update = &edsResp{ctx: ctx, resp: u}
|
|
||||||
default:
|
|
||||||
grpclog.Warningf("xdsBalancer: got a response that's not EDS, type = %T", u)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case x.xdsClientUpdate <- update:
|
case x.xdsClientUpdate <- &edsResp{ctx: ctx, resp: resp}:
|
||||||
case <-x.ctx.Done():
|
case <-x.ctx.Done():
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ import (
|
|||||||
|
|
||||||
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
xdsgrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2"
|
xdsgrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"github.com/golang/protobuf/ptypes"
|
"github.com/golang/protobuf/ptypes"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
@ -34,6 +33,7 @@ import (
|
|||||||
"google.golang.org/grpc/internal/backoff"
|
"google.golang.org/grpc/internal/backoff"
|
||||||
"google.golang.org/grpc/internal/channelz"
|
"google.golang.org/grpc/internal/channelz"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
"google.golang.org/grpc/xds/internal/client/bootstrap"
|
"google.golang.org/grpc/xds/internal/client/bootstrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ type client struct {
|
|||||||
cli xdsgrpc.AggregatedDiscoveryServiceClient
|
cli xdsgrpc.AggregatedDiscoveryServiceClient
|
||||||
dialer func(context.Context, string) (net.Conn, error)
|
dialer func(context.Context, string) (net.Conn, error)
|
||||||
channelzParentID int64
|
channelzParentID int64
|
||||||
newADS func(ctx context.Context, resp proto.Message) error
|
newADS func(ctx context.Context, resp *xdsclient.EDSUpdate) error
|
||||||
loseContact func(ctx context.Context)
|
loseContact func(ctx context.Context)
|
||||||
cleanup func()
|
cleanup func()
|
||||||
backoff backoff.Strategy
|
backoff backoff.Strategy
|
||||||
@ -197,7 +197,12 @@ func (c *client) adsCallAttempt() (firstRespReceived bool) {
|
|||||||
grpclog.Warningf("xds: failed to unmarshal resources due to %v.", err)
|
grpclog.Warningf("xds: failed to unmarshal resources due to %v.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := c.newADS(c.ctx, adsResp.Message); err != nil {
|
parsed, err := xdsclient.ParseEDSRespProto(adsResp.Message.(*xdspb.ClusterLoadAssignment))
|
||||||
|
if err != nil {
|
||||||
|
grpclog.Warningf("xds: parsing new EDS message failed due to %v.", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := c.newADS(c.ctx, parsed); err != nil {
|
||||||
grpclog.Warningf("xds: processing new ADS message failed due to %v.", err)
|
grpclog.Warningf("xds: processing new ADS message failed due to %v.", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -213,7 +218,7 @@ func (c *client) adsCallAttempt() (firstRespReceived bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newXDSClient(balancerName string, edsServiceName string, opts balancer.BuildOptions, loadStore lrs.Store, newADS func(context.Context, proto.Message) error, loseContact func(ctx context.Context), exitCleanup func()) *client {
|
func newXDSClient(balancerName string, edsServiceName string, opts balancer.BuildOptions, loadStore lrs.Store, newADS func(context.Context, *xdsclient.EDSUpdate) error, loseContact func(ctx context.Context), exitCleanup func()) *client {
|
||||||
c := &client{
|
c := &client{
|
||||||
serviceName: edsServiceName,
|
serviceName: edsServiceName,
|
||||||
dialer: opts.Dialer,
|
dialer: opts.Dialer,
|
||||||
|
@ -35,11 +35,13 @@ import (
|
|||||||
durationpb "github.com/golang/protobuf/ptypes/duration"
|
durationpb "github.com/golang/protobuf/ptypes/duration"
|
||||||
structpb "github.com/golang/protobuf/ptypes/struct"
|
structpb "github.com/golang/protobuf/ptypes/struct"
|
||||||
wrpb "github.com/golang/protobuf/ptypes/wrappers"
|
wrpb "github.com/golang/protobuf/ptypes/wrappers"
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -233,8 +235,8 @@ func (s) TestXdsClientResponseHandling(t *testing.T) {
|
|||||||
func testXdsClientResponseHandling(t *testing.T, test *testConfig) {
|
func testXdsClientResponseHandling(t *testing.T, test *testConfig) {
|
||||||
addr, td, _, cleanup := setupServer(t)
|
addr, td, _, cleanup := setupServer(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
adsChan := make(chan proto.Message, 10)
|
adsChan := make(chan *xdsclient.EDSUpdate, 10)
|
||||||
newADS := func(ctx context.Context, i proto.Message) error {
|
newADS := func(ctx context.Context, i *xdsclient.EDSUpdate) error {
|
||||||
adsChan <- i
|
adsChan <- i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -255,7 +257,11 @@ func testXdsClientResponseHandling(t *testing.T, test *testConfig) {
|
|||||||
for i, resp := range test.responsesToSend {
|
for i, resp := range test.responsesToSend {
|
||||||
td.sendResp(&response{resp: resp})
|
td.sendResp(&response{resp: resp})
|
||||||
ads := <-adsChan
|
ads := <-adsChan
|
||||||
if !proto.Equal(ads, test.expectedADSResponses[i]) {
|
want, err := xdsclient.ParseEDSRespProto(test.expectedADSResponses[i].(*xdspb.ClusterLoadAssignment))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parsing wanted EDS response failed: %v", err)
|
||||||
|
}
|
||||||
|
if !cmp.Equal(ads, want) {
|
||||||
t.Fatalf("received unexpected ads response, got %v, want %v", ads, test.expectedADSResponses[i])
|
t.Fatalf("received unexpected ads response, got %v, want %v", ads, test.expectedADSResponses[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,8 +292,8 @@ func (s) TestXdsClientLoseContact(t *testing.T) {
|
|||||||
func testXdsClientLoseContactRemoteClose(t *testing.T, test *testConfig) {
|
func testXdsClientLoseContactRemoteClose(t *testing.T, test *testConfig) {
|
||||||
addr, td, _, cleanup := setupServer(t)
|
addr, td, _, cleanup := setupServer(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
adsChan := make(chan proto.Message, 10)
|
adsChan := make(chan *xdsclient.EDSUpdate, 10)
|
||||||
newADS := func(ctx context.Context, i proto.Message) error {
|
newADS := func(ctx context.Context, i *xdsclient.EDSUpdate) error {
|
||||||
adsChan <- i
|
adsChan <- i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -320,8 +326,8 @@ func testXdsClientLoseContactADSRelatedErrorOccur(t *testing.T, test *testConfig
|
|||||||
addr, td, _, cleanup := setupServer(t)
|
addr, td, _, cleanup := setupServer(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
adsChan := make(chan proto.Message, 10)
|
adsChan := make(chan *xdsclient.EDSUpdate, 10)
|
||||||
newADS := func(ctx context.Context, i proto.Message) error {
|
newADS := func(ctx context.Context, i *xdsclient.EDSUpdate) error {
|
||||||
adsChan <- i
|
adsChan <- i
|
||||||
return test.adsErr
|
return test.adsErr
|
||||||
}
|
}
|
||||||
@ -354,8 +360,8 @@ func (s) TestXdsClientExponentialRetry(t *testing.T) {
|
|||||||
addr, td, _, cleanup := setupServer(t)
|
addr, td, _, cleanup := setupServer(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
adsChan := make(chan proto.Message, 10)
|
adsChan := make(chan *xdsclient.EDSUpdate, 10)
|
||||||
newADS := func(ctx context.Context, i proto.Message) error {
|
newADS := func(ctx context.Context, i *xdsclient.EDSUpdate) error {
|
||||||
adsChan <- i
|
adsChan <- i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
|
|
||||||
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
"github.com/golang/protobuf/jsonpb"
|
"github.com/golang/protobuf/jsonpb"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
wrapperspb "github.com/golang/protobuf/ptypes/wrappers"
|
wrapperspb "github.com/golang/protobuf/ptypes/wrappers"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"google.golang.org/grpc/balancer"
|
"google.golang.org/grpc/balancer"
|
||||||
@ -39,6 +38,7 @@ import (
|
|||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
"google.golang.org/grpc/xds/internal/balancer/lrs"
|
||||||
|
xdsclient "google.golang.org/grpc/xds/internal/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
var lbABuilder = &balancerABuilder{}
|
var lbABuilder = &balancerABuilder{}
|
||||||
@ -178,7 +178,7 @@ type scStateChange struct {
|
|||||||
|
|
||||||
type fakeEDSBalancer struct {
|
type fakeEDSBalancer struct {
|
||||||
cc balancer.ClientConn
|
cc balancer.ClientConn
|
||||||
edsChan chan *xdspb.ClusterLoadAssignment
|
edsChan chan *xdsclient.EDSUpdate
|
||||||
childPolicy chan *loadBalancingConfig
|
childPolicy chan *loadBalancingConfig
|
||||||
fallbackPolicy chan *loadBalancingConfig
|
fallbackPolicy chan *loadBalancingConfig
|
||||||
subconnStateChange chan *scStateChange
|
subconnStateChange chan *scStateChange
|
||||||
@ -195,7 +195,7 @@ func (f *fakeEDSBalancer) Close() {
|
|||||||
latestFakeEdsBalancer = nil
|
latestFakeEdsBalancer = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeEDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment) {
|
func (f *fakeEDSBalancer) HandleEDSResponse(edsResp *xdsclient.EDSUpdate) {
|
||||||
f.edsChan <- edsResp
|
f.edsChan <- edsResp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +209,7 @@ func (f *fakeEDSBalancer) HandleChildPolicy(name string, config json.RawMessage)
|
|||||||
func newFakeEDSBalancer(cc balancer.ClientConn, loadStore lrs.Store) edsBalancerInterface {
|
func newFakeEDSBalancer(cc balancer.ClientConn, loadStore lrs.Store) edsBalancerInterface {
|
||||||
lb := &fakeEDSBalancer{
|
lb := &fakeEDSBalancer{
|
||||||
cc: cc,
|
cc: cc,
|
||||||
edsChan: make(chan *xdspb.ClusterLoadAssignment, 10),
|
edsChan: make(chan *xdsclient.EDSUpdate, 10),
|
||||||
childPolicy: make(chan *loadBalancingConfig, 10),
|
childPolicy: make(chan *loadBalancingConfig, 10),
|
||||||
fallbackPolicy: make(chan *loadBalancingConfig, 10),
|
fallbackPolicy: make(chan *loadBalancingConfig, 10),
|
||||||
subconnStateChange: make(chan *scStateChange, 10),
|
subconnStateChange: make(chan *scStateChange, 10),
|
||||||
@ -349,7 +349,11 @@ func (s) TestXdsBalanceHandleBalancerConfigBalancerNameUpdate(t *testing.T) {
|
|||||||
if edsLB := getLatestEdsBalancer(); edsLB != nil { // edsLB won't change between the two iterations
|
if edsLB := getLatestEdsBalancer(); edsLB != nil { // edsLB won't change between the two iterations
|
||||||
select {
|
select {
|
||||||
case gotEDS := <-edsLB.edsChan:
|
case gotEDS := <-edsLB.edsChan:
|
||||||
if !proto.Equal(gotEDS, testClusterLoadAssignment) {
|
want, err := xdsclient.ParseEDSRespProto(testClusterLoadAssignment)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parsing wanted EDS response failed: %v", err)
|
||||||
|
}
|
||||||
|
if !cmp.Equal(gotEDS, want) {
|
||||||
t.Fatalf("edsBalancer got eds: %v, want %v", gotEDS, testClusterLoadAssignment)
|
t.Fatalf("edsBalancer got eds: %v, want %v", gotEDS, testClusterLoadAssignment)
|
||||||
}
|
}
|
||||||
case <-time.After(time.Second):
|
case <-time.After(time.Second):
|
||||||
|
163
xds/internal/client/eds.go
Normal file
163
xds/internal/client/eds.go
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2019 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed 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 (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
|
corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
||||||
|
endpointpb "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
|
||||||
|
typepb "github.com/envoyproxy/go-control-plane/envoy/type"
|
||||||
|
"google.golang.org/grpc/xds/internal"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OverloadDropConfig contains the config to drop overloads.
|
||||||
|
type OverloadDropConfig struct {
|
||||||
|
Category string
|
||||||
|
Numerator uint32
|
||||||
|
Denominator uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointHealthStatus represents the health status of an endpoint.
|
||||||
|
type EndpointHealthStatus int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// EndpointHealthStatusUnknown represents HealthStatus UNKNOWN.
|
||||||
|
EndpointHealthStatusUnknown EndpointHealthStatus = iota
|
||||||
|
// EndpointHealthStatusHealthy represents HealthStatus HEALTHY.
|
||||||
|
EndpointHealthStatusHealthy
|
||||||
|
// EndpointHealthStatusUnhealthy represents HealthStatus UNHEALTHY.
|
||||||
|
EndpointHealthStatusUnhealthy
|
||||||
|
// EndpointHealthStatusDraining represents HealthStatus DRAINING.
|
||||||
|
EndpointHealthStatusDraining
|
||||||
|
// EndpointHealthStatusTimeout represents HealthStatus TIMEOUT.
|
||||||
|
EndpointHealthStatusTimeout
|
||||||
|
// EndpointHealthStatusDegraded represents HealthStatus DEGRADED.
|
||||||
|
EndpointHealthStatusDegraded
|
||||||
|
)
|
||||||
|
|
||||||
|
// Endpoint contains information of an endpoint.
|
||||||
|
type Endpoint struct {
|
||||||
|
Address string
|
||||||
|
HealthStatus EndpointHealthStatus
|
||||||
|
Weight uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locality contains information of a locality.
|
||||||
|
type Locality struct {
|
||||||
|
Endpoints []Endpoint
|
||||||
|
ID internal.Locality
|
||||||
|
Priority uint32
|
||||||
|
Weight uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// EDSUpdate contains an EDS update.
|
||||||
|
type EDSUpdate struct {
|
||||||
|
Drops []OverloadDropConfig
|
||||||
|
Localities []Locality
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAddress(socketAddress *corepb.SocketAddress) string {
|
||||||
|
return net.JoinHostPort(socketAddress.GetAddress(), strconv.Itoa(int(socketAddress.GetPortValue())))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseDropPolicy(dropPolicy *xdspb.ClusterLoadAssignment_Policy_DropOverload) OverloadDropConfig {
|
||||||
|
percentage := dropPolicy.GetDropPercentage()
|
||||||
|
var (
|
||||||
|
numerator = percentage.GetNumerator()
|
||||||
|
denominator uint32
|
||||||
|
)
|
||||||
|
switch percentage.GetDenominator() {
|
||||||
|
case typepb.FractionalPercent_HUNDRED:
|
||||||
|
denominator = 100
|
||||||
|
case typepb.FractionalPercent_TEN_THOUSAND:
|
||||||
|
denominator = 10000
|
||||||
|
case typepb.FractionalPercent_MILLION:
|
||||||
|
denominator = 1000000
|
||||||
|
}
|
||||||
|
return OverloadDropConfig{
|
||||||
|
Category: dropPolicy.GetCategory(),
|
||||||
|
Numerator: numerator,
|
||||||
|
Denominator: denominator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseEndpoints(lbEndpoints []*endpointpb.LbEndpoint) []Endpoint {
|
||||||
|
endpoints := make([]Endpoint, 0, len(lbEndpoints))
|
||||||
|
for _, lbEndpoint := range lbEndpoints {
|
||||||
|
endpoints = append(endpoints, Endpoint{
|
||||||
|
HealthStatus: EndpointHealthStatus(lbEndpoint.GetHealthStatus()),
|
||||||
|
Address: parseAddress(lbEndpoint.GetEndpoint().GetAddress().GetSocketAddress()),
|
||||||
|
Weight: lbEndpoint.GetLoadBalancingWeight().GetValue(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return endpoints
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseEDSRespProto turns EDS response proto message to EDSUpdate.
|
||||||
|
//
|
||||||
|
// This is temporarily exported to be used in eds balancer, before it switches
|
||||||
|
// to use xds client. TODO: unexport.
|
||||||
|
func ParseEDSRespProto(m *xdspb.ClusterLoadAssignment) (*EDSUpdate, error) {
|
||||||
|
ret := &EDSUpdate{}
|
||||||
|
for _, dropPolicy := range m.GetPolicy().GetDropOverloads() {
|
||||||
|
ret.Drops = append(ret.Drops, parseDropPolicy(dropPolicy))
|
||||||
|
}
|
||||||
|
priorities := make(map[uint32]struct{})
|
||||||
|
for _, locality := range m.Endpoints {
|
||||||
|
l := locality.GetLocality()
|
||||||
|
if l == nil {
|
||||||
|
return nil, fmt.Errorf("EDS response contains a locality without ID, locality: %+v", locality)
|
||||||
|
}
|
||||||
|
lid := internal.Locality{
|
||||||
|
Region: l.Region,
|
||||||
|
Zone: l.Zone,
|
||||||
|
SubZone: l.SubZone,
|
||||||
|
}
|
||||||
|
priority := locality.GetPriority()
|
||||||
|
priorities[priority] = struct{}{}
|
||||||
|
ret.Localities = append(ret.Localities, Locality{
|
||||||
|
ID: lid,
|
||||||
|
Endpoints: parseEndpoints(locality.GetLbEndpoints()),
|
||||||
|
Weight: locality.GetLoadBalancingWeight().GetValue(),
|
||||||
|
Priority: priority,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for i := 0; i < len(priorities); i++ {
|
||||||
|
if _, ok := priorities[uint32(i)]; !ok {
|
||||||
|
return nil, fmt.Errorf("priority %v missing (with different priorities %v received)", i, priorities)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseEDSRespProtoForTesting parses EDS response, and panic if parsing fails.
|
||||||
|
// This is used by EDS balancer tests.
|
||||||
|
//
|
||||||
|
// TODO: delete this. The EDS balancer should build an EDSUpdate directly,
|
||||||
|
// instead of building and parsing a proto message.
|
||||||
|
func ParseEDSRespProtoForTesting(m *xdspb.ClusterLoadAssignment) *EDSUpdate {
|
||||||
|
u, err := ParseEDSRespProto(m)
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
39
xds/internal/client/eds_test.go
Normal file
39
xds/internal/client/eds_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2019 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed 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 (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Only error cases are tested, normal cases are covered because EDS balancer
|
||||||
|
// tests build an EDS responses and parses them.
|
||||||
|
// TODO: add more tests, with error cases and normal cases.
|
||||||
|
|
||||||
|
// Test that parsing fails if EDS response doesn't have all priorities.
|
||||||
|
// Priorities should range from 0 (highest) to N (lowest) without skipping
|
||||||
|
func TestParseEDSRespProtoPriorityError(t *testing.T) {
|
||||||
|
clab0 := NewClusterLoadAssignmentBuilder("test", nil)
|
||||||
|
clab0.AddLocality("locality-1", 1, 0, []string{"addr1:314"}, nil)
|
||||||
|
clab0.AddLocality("locality-2", 1, 2, []string{"addr2:159"}, nil)
|
||||||
|
_, err := ParseEDSRespProto(clab0.Build())
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("ParseEDSRespProto() error = %v, wantErr <non-nil>", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
117
xds/internal/client/eds_testutil.go
Normal file
117
xds/internal/client/eds_testutil.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2019 gRPC authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// All structs/functions in this file should be unexported. They are used in EDS
|
||||||
|
// balancer tests now, to generate test inputs. Eventually, EDS balancer tests
|
||||||
|
// should generate EDSUpdate directly, instead of generating and parsing the
|
||||||
|
// proto message.
|
||||||
|
// TODO: unexported everything in this file.
|
||||||
|
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
|
||||||
|
corepb "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
|
||||||
|
endpointpb "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
|
||||||
|
typepb "github.com/envoyproxy/go-control-plane/envoy/type"
|
||||||
|
wrapperspb "github.com/golang/protobuf/ptypes/wrappers"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ClusterLoadAssignmentBuilder builds a ClusterLoadAssignment, aka EDS
|
||||||
|
// response.
|
||||||
|
type ClusterLoadAssignmentBuilder struct {
|
||||||
|
v *xdspb.ClusterLoadAssignment
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClusterLoadAssignmentBuilder creates a ClusterLoadAssignmentBuilder.
|
||||||
|
func NewClusterLoadAssignmentBuilder(clusterName string, dropPercents []uint32) *ClusterLoadAssignmentBuilder {
|
||||||
|
var drops []*xdspb.ClusterLoadAssignment_Policy_DropOverload
|
||||||
|
for i, d := range dropPercents {
|
||||||
|
drops = append(drops, &xdspb.ClusterLoadAssignment_Policy_DropOverload{
|
||||||
|
Category: fmt.Sprintf("test-drop-%d", i),
|
||||||
|
DropPercentage: &typepb.FractionalPercent{
|
||||||
|
Numerator: d,
|
||||||
|
Denominator: typepb.FractionalPercent_HUNDRED,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ClusterLoadAssignmentBuilder{
|
||||||
|
v: &xdspb.ClusterLoadAssignment{
|
||||||
|
ClusterName: clusterName,
|
||||||
|
Policy: &xdspb.ClusterLoadAssignment_Policy{
|
||||||
|
DropOverloads: drops,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLocalityOptions contains options when adding locality to the builder.
|
||||||
|
type AddLocalityOptions struct {
|
||||||
|
Health []corepb.HealthStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddLocality adds a locality to the builder.
|
||||||
|
func (clab *ClusterLoadAssignmentBuilder) AddLocality(subzone string, weight uint32, priority uint32, addrsWithPort []string, opts *AddLocalityOptions) {
|
||||||
|
var lbEndPoints []*endpointpb.LbEndpoint
|
||||||
|
for i, a := range addrsWithPort {
|
||||||
|
host, portStr, err := net.SplitHostPort(a)
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to split " + a)
|
||||||
|
}
|
||||||
|
port, err := strconv.Atoi(portStr)
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to atoi " + portStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
lbe := &endpointpb.LbEndpoint{
|
||||||
|
HostIdentifier: &endpointpb.LbEndpoint_Endpoint{
|
||||||
|
Endpoint: &endpointpb.Endpoint{
|
||||||
|
Address: &corepb.Address{
|
||||||
|
Address: &corepb.Address_SocketAddress{
|
||||||
|
SocketAddress: &corepb.SocketAddress{
|
||||||
|
Protocol: corepb.SocketAddress_TCP,
|
||||||
|
Address: host,
|
||||||
|
PortSpecifier: &corepb.SocketAddress_PortValue{
|
||||||
|
PortValue: uint32(port)}}}}}},
|
||||||
|
}
|
||||||
|
if opts != nil && i < len(opts.Health) {
|
||||||
|
lbe.HealthStatus = opts.Health[i]
|
||||||
|
}
|
||||||
|
lbEndPoints = append(lbEndPoints, lbe)
|
||||||
|
}
|
||||||
|
|
||||||
|
clab.v.Endpoints = append(clab.v.Endpoints, &endpointpb.LocalityLbEndpoints{
|
||||||
|
Locality: &corepb.Locality{
|
||||||
|
Region: "",
|
||||||
|
Zone: "",
|
||||||
|
SubZone: subzone,
|
||||||
|
},
|
||||||
|
LbEndpoints: lbEndPoints,
|
||||||
|
LoadBalancingWeight: &wrapperspb.UInt32Value{Value: weight},
|
||||||
|
Priority: priority,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build builds ClusterLoadAssignment.
|
||||||
|
func (clab *ClusterLoadAssignmentBuilder) Build() *xdspb.ClusterLoadAssignment {
|
||||||
|
return clab.v
|
||||||
|
}
|
@ -30,6 +30,8 @@ import (
|
|||||||
//
|
//
|
||||||
// This struct should only be used as map keys. Use the proto message directly
|
// This struct should only be used as map keys. Use the proto message directly
|
||||||
// in all other places.
|
// in all other places.
|
||||||
|
//
|
||||||
|
// TODO: rename to LocalityID.
|
||||||
type Locality struct {
|
type Locality struct {
|
||||||
Region string
|
Region string
|
||||||
Zone string
|
Zone string
|
||||||
|
Reference in New Issue
Block a user