diff --git a/balancer/rls/internal/config.go b/balancer/rls/internal/config.go index 94ed3c5ee70b..305c09106ba3 100644 --- a/balancer/rls/internal/config.go +++ b/balancer/rls/internal/config.go @@ -61,7 +61,6 @@ type lbConfig struct { maxAge time.Duration staleAge time.Duration cacheSizeBytes int64 - rpStrategy rlspb.RouteLookupConfig_RequestProcessingStrategy defaultTarget string cpName string cpTargetField string @@ -75,7 +74,6 @@ func (lbCfg *lbConfig) Equal(other *lbConfig) bool { lbCfg.maxAge == other.maxAge && lbCfg.staleAge == other.staleAge && lbCfg.cacheSizeBytes == other.cacheSizeBytes && - lbCfg.rpStrategy == other.rpStrategy && lbCfg.defaultTarget == other.defaultTarget && lbCfg.cpName == other.cpName && lbCfg.cpTargetField == other.cpTargetField && @@ -167,11 +165,6 @@ func (l *loadBalancingConfig) UnmarshalJSON(data []byte) error { // - must be greater than zero // - TODO(easwars): Define a minimum value for this field, to be used when // left unspecified -// ** request_processing_strategy field: -// - must have a value other than STRATEGY_UNSPECIFIED -// - if set to SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR or -// ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, the default_target field must be -// set to a non-empty value // * childPolicy field: // - must find a valid child policy with a valid config (the child policy must // be able to parse the provided config successfully when we pass it a dummy @@ -242,22 +235,10 @@ func (*rlsBB) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingConfig, logger.Infof("rls: max_age in service config is %v, using %v", maxAge, maxMaxAge) maxAge = maxMaxAge } - cacheSizeBytes := rlsProto.GetCacheSizeBytes() if cacheSizeBytes <= 0 { return nil, fmt.Errorf("rls: cache_size_bytes must be greater than 0 in service config {%+v}", string(c)) } - - rpStrategy := rlsProto.GetRequestProcessingStrategy() - if rpStrategy == rlspb.RouteLookupConfig_STRATEGY_UNSPECIFIED { - return nil, fmt.Errorf("rls: request_processing_strategy cannot be left unspecified in service config {%+v}", string(c)) - } - defaultTarget := rlsProto.GetDefaultTarget() - if (rpStrategy == rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR || - rpStrategy == rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS) && defaultTarget == "" { - return nil, fmt.Errorf("rls: request_processing_strategy is %s, but default_target is not set", rpStrategy.String()) - } - if childPolicy == nil { return nil, fmt.Errorf("rls: childPolicy is invalid in service config {%+v}", string(c)) } @@ -283,8 +264,7 @@ func (*rlsBB) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingConfig, maxAge: maxAge, staleAge: staleAge, cacheSizeBytes: cacheSizeBytes, - rpStrategy: rpStrategy, - defaultTarget: defaultTarget, + defaultTarget: rlsProto.GetDefaultTarget(), // TODO(easwars): Once we refactor validateChildPolicyConfig and make // it a method on the lbConfig object, we could directly store the // balancer.Builder and/or balancer.ConfigParser here instead of the diff --git a/balancer/rls/internal/config_test.go b/balancer/rls/internal/config_test.go index fa22e15a6501..1efd054512b2 100644 --- a/balancer/rls/internal/config_test.go +++ b/balancer/rls/internal/config_test.go @@ -28,8 +28,7 @@ import ( "github.com/google/go-cmp/cmp" "google.golang.org/grpc/balancer" - _ "google.golang.org/grpc/balancer/grpclb" // grpclb for config parsing. - rlspb "google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1" + _ "google.golang.org/grpc/balancer/grpclb" // grpclb for config parsing. _ "google.golang.org/grpc/internal/resolver/passthrough" // passthrough resolver. ) @@ -58,7 +57,6 @@ func testEqual(a, b *lbConfig) bool { a.maxAge == b.maxAge && a.staleAge == b.staleAge && a.cacheSizeBytes == b.cacheSizeBytes && - a.rpStrategy == b.rpStrategy && a.defaultTarget == b.defaultTarget && a.cpName == b.cpName && a.cpTargetField == b.cpTargetField && @@ -91,7 +89,6 @@ func TestParseConfig(t *testing.T) { "maxAge" : "500s", "staleAge": "600s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" }, "childPolicy": [ @@ -107,7 +104,6 @@ func TestParseConfig(t *testing.T) { maxAge: 5 * time.Minute, // This is max maxAge. staleAge: time.Duration(0), // StaleAge is ignore because it was higher than maxAge. cacheSizeBytes: 1000, - rpStrategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, defaultTarget: "passthrough:///default", cpName: "grpclb", cpTargetField: "service_name", @@ -127,7 +123,6 @@ func TestParseConfig(t *testing.T) { "maxAge": "60s", "staleAge" : "50s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" }, "childPolicy": [{"grpclb": {"childPolicy": [{"pickfirst": {}}]}}], @@ -139,7 +134,6 @@ func TestParseConfig(t *testing.T) { maxAge: 60 * time.Second, staleAge: 50 * time.Second, cacheSizeBytes: 1000, - rpStrategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, defaultTarget: "passthrough:///default", cpName: "grpclb", cpTargetField: "service_name", @@ -288,41 +282,6 @@ func TestParseConfigErrors(t *testing.T) { }`), wantErr: "rls: cache_size_bytes must be greater than 0 in service config", }, - { - desc: "invalid request processing strategy", - input: []byte(`{ - "routeLookupConfig": { - "grpcKeybuilders": [{ - "names": [{"service": "service", "method": "method"}], - "headers": [{"key": "k1", "names": ["v1"]}] - }], - "lookupService": "passthrough:///target", - "lookupServiceTimeout" : "10s", - "maxAge": "30s", - "staleAge" : "25s", - "cacheSizeBytes": 1000 - } - }`), - wantErr: "rls: request_processing_strategy cannot be left unspecified in service config", - }, - { - desc: "request processing strategy without default target", - input: []byte(`{ - "routeLookupConfig": { - "grpcKeybuilders": [{ - "names": [{"service": "service", "method": "method"}], - "headers": [{"key": "k1", "names": ["v1"]}] - }], - "lookupService": "passthrough:///target", - "lookupServiceTimeout" : "10s", - "maxAge": "30s", - "staleAge" : "25s", - "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS" - } - }`), - wantErr: "default_target is not set", - }, { desc: "no child policy", input: []byte(`{ @@ -336,7 +295,6 @@ func TestParseConfigErrors(t *testing.T) { "maxAge": "30s", "staleAge" : "25s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" } }`), @@ -355,7 +313,6 @@ func TestParseConfigErrors(t *testing.T) { "maxAge": "30s", "staleAge" : "25s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" }, "childPolicy": [ @@ -378,7 +335,6 @@ func TestParseConfigErrors(t *testing.T) { "maxAge": "30s", "staleAge" : "25s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" }, "childPolicy": [ @@ -402,7 +358,6 @@ func TestParseConfigErrors(t *testing.T) { "maxAge": "30s", "staleAge" : "25s", "cacheSizeBytes": 1000, - "request_processing_strategy": "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", "defaultTarget": "passthrough:///default" }, "childPolicy": [ diff --git a/balancer/rls/internal/picker.go b/balancer/rls/internal/picker.go index ce7100536d95..738449446558 100644 --- a/balancer/rls/internal/picker.go +++ b/balancer/rls/internal/picker.go @@ -25,7 +25,6 @@ import ( "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/rls/internal/cache" "google.golang.org/grpc/balancer/rls/internal/keys" - rlspb "google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1" "google.golang.org/grpc/metadata" ) @@ -42,10 +41,6 @@ type rlsPicker struct { // The keyBuilder map used to generate RLS keys for the RPC. This is built // by the LB policy based on the received ServiceConfig. kbm keys.BuilderMap - // This is the request processing strategy as indicated by the LB policy's - // ServiceConfig. This controls how to process a RPC when the data required - // to make the pick decision is not in the cache. - strategy rlspb.RouteLookupConfig_RequestProcessingStrategy // The following hooks are setup by the LB policy to enable the rlsPicker to // access state stored in the policy. This approach has the following @@ -79,15 +74,6 @@ type rlsPicker struct { defaultPick func(balancer.PickInfo) (balancer.PickResult, error) } -// This helper function decides if the pick should delegate to the default -// rlsPicker based on the request processing strategy. This is used when the -// data cache does not have a valid entry for the current RPC and the RLS -// request is throttled, or if the current data cache entry is in backoff. -func (p *rlsPicker) shouldDelegateToDefault() bool { - return p.strategy == rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR || - p.strategy == rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS -} - // Pick makes the routing decision for every outbound RPC. func (p *rlsPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { // For every incoming request, we first build the RLS keys using the @@ -123,9 +109,9 @@ func (p *rlsPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { if p.shouldThrottle() { // The entry doesn't exist or has expired and the new RLS request // has been throttled. Treat it as an error and delegate to default - // pick or fail the pick, based on the request processing strategy. + // pick, if one exists, or fail the pick. if entry == nil || entry.ExpiryTime.Before(now) { - if p.shouldDelegateToDefault() { + if p.defaultPick != nil { return p.defaultPick(info) } return balancer.PickResult{}, errRLSThrottled @@ -144,25 +130,20 @@ func (p *rlsPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { // this cache entry. return entry.ChildPicker.Pick(info) } else if entry.BackoffTime.After(now) { - // The entry has expired, but is in backoff. We either delegate to - // the default rlsPicker or return the error from the last failed - // RLS request for this entry. - if p.shouldDelegateToDefault() { + // The entry has expired, but is in backoff. We delegate to the + // default pick, if one exists, or return the error from the last + // failed RLS request for this entry. + if p.defaultPick != nil { return p.defaultPick(info) } return balancer.PickResult{}, entry.CallStatus } } - // Either we didn't find an entry or found an entry which had expired and - // was not in backoff (which is also essentially equivalent to not finding - // an entry), and we started an RLS request in the background. We either - // queue the pick or delegate to the default pick. In the former case, upon - // receipt of an RLS response, the LB policy will send a new rlsPicker to - // the channel, and the pick will be retried. - if p.strategy == rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR || - p.strategy == rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR { - return balancer.PickResult{}, balancer.ErrNoSubConnAvailable - } - return p.defaultPick(info) + // We get here only in the following cases: + // * No data cache entry or expired entry, RLS request sent out + // * No valid data cache entry and Pending cache entry exists + // We need to queue to pick which will be handled once the RLS response is + // received. + return balancer.PickResult{}, balancer.ErrNoSubConnAvailable } diff --git a/balancer/rls/internal/picker_test.go b/balancer/rls/internal/picker_test.go index fc5f935d6929..1397bf8085d8 100644 --- a/balancer/rls/internal/picker_test.go +++ b/balancer/rls/internal/picker_test.go @@ -27,6 +27,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "google.golang.org/grpc/balancer" "google.golang.org/grpc/balancer/rls/internal/cache" "google.golang.org/grpc/balancer/rls/internal/keys" @@ -38,6 +39,12 @@ import ( const defaultTestMaxAge = 5 * time.Second +// initKeyBuilderMap initializes a keyBuilderMap of the form: +// { +// "gFoo": "k1=n1", +// "gBar/method1": "k2=n21,n22" +// "gFoobar": "k3=n3", +// } func initKeyBuilderMap() (keys.BuilderMap, error) { kb1 := &rlspb.GrpcKeyBuilder{ Names: []*rlspb.GrpcKeyBuilder_Name{{Service: "gFoo"}}, @@ -63,15 +70,33 @@ type fakeSubConn struct { id int } -// fakeChildPicker sends a PickResult with a fakeSubConn with the configured id. -type fakeChildPicker struct { +// fakePicker sends a PickResult with a fakeSubConn with the configured id. +type fakePicker struct { id int } -func (p *fakeChildPicker) Pick(_ balancer.PickInfo) (balancer.PickResult, error) { +func (p *fakePicker) Pick(_ balancer.PickInfo) (balancer.PickResult, error) { return balancer.PickResult{SubConn: &fakeSubConn{id: p.id}}, nil } +// newFakePicker returns a fakePicker configured with a random ID. The subConns +// returned by this picker are of type fakefakeSubConn, and contain the same +// random ID, which tests can use to verify. +func newFakePicker() *fakePicker { + return &fakePicker{id: grpcrand.Intn(math.MaxInt32)} +} + +func verifySubConn(sc balancer.SubConn, wantID int) error { + fsc, ok := sc.(*fakeSubConn) + if !ok { + return fmt.Errorf("Pick() returned a SubConn of type %T, want %T", sc, &fakeSubConn{}) + } + if fsc.id != wantID { + return fmt.Errorf("Pick() returned SubConn %d, want %d", fsc.id, wantID) + } + return nil +} + // TestPickKeyBuilder verifies the different possible scenarios for forming an // RLS key for an incoming RPC. func TestPickKeyBuilder(t *testing.T) { @@ -110,8 +135,7 @@ func TestPickKeyBuilder(t *testing.T) { t.Run(test.desc, func(t *testing.T) { randID := grpcrand.Intn(math.MaxInt32) p := rlsPicker{ - kbm: kbm, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, + kbm: kbm, readCache: func(key cache.Key) (*cache.Entry, bool) { if !cmp.Equal(key, test.wantKey) { t.Fatalf("rlsPicker using cacheKey %v, want %v", key, test.wantKey) @@ -124,7 +148,7 @@ func TestPickKeyBuilder(t *testing.T) { // Cache entry is configured with a child policy whose // rlsPicker always returns an empty PickResult and nil // error. - ChildPicker: &fakeChildPicker{id: randID}, + ChildPicker: &fakePicker{id: randID}, }, false }, // The other hooks are not set here because they are not expected to be @@ -149,7 +173,9 @@ func TestPickKeyBuilder(t *testing.T) { } } -func TestPick(t *testing.T) { +// TestPick_DataCacheMiss_PendingCacheMiss verifies different Pick scenarios +// where the entry is neither found in the data cache nor in the pending cache. +func TestPick_DataCacheMiss_PendingCacheMiss(t *testing.T) { const ( rpcPath = "/gFoo/method" wantKeyMapStr = "k1=v1" @@ -160,369 +186,275 @@ func TestPick(t *testing.T) { } md := metadata.New(map[string]string{"n1": "v1", "n3": "v3"}) wantKey := cache.Key{Path: rpcPath, KeyMap: wantKeyMapStr} - rlsLastErr := errors.New("last RLS request failed") tests := []struct { desc string - // The cache entry, as returned by the overridden readCache hook. - cacheEntry *cache.Entry - // Whether or not a pending entry exists, as returned by the overridden - // readCache hook. - pending bool + // Whether or not a default target is configured. + defaultPickExists bool // Whether or not the RLS request should be throttled. throttle bool // Whether or not the test is expected to make a new RLS request. - newRLSRequest bool - // Whether or not the test ends up delegating to the default pick. - useDefaultPick bool - // Whether or not the test ends up delegating to the child policy in - // the cache entry. - useChildPick bool - // Request processing strategy as used by the rlsPicker. - strategy rlspb.RouteLookupConfig_RequestProcessingStrategy + wantRLSRequest bool // Expected error returned by the rlsPicker under test. wantErr error }{ { - desc: "cacheMiss_pending_defaultTargetOnError", - pending: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, + desc: "rls request throttled with default pick", + defaultPickExists: true, + throttle: true, }, { - desc: "cacheMiss_pending_clientSeesError", - pending: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, - }, - { - desc: "cacheMiss_pending_defaultTargetOnMiss", - pending: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheMiss_noPending_notThrottled_defaultTargetOnError", - newRLSRequest: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, - }, - { - desc: "cacheMiss_noPending_notThrottled_clientSeesError", - newRLSRequest: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, - }, - { - desc: "cacheMiss_noPending_notThrottled_defaultTargetOnMiss", - newRLSRequest: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheMiss_noPending_throttled_defaultTargetOnError", - throttle: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheMiss_noPending_throttled_clientSeesError", + desc: "rls request throttled without default pick", throttle: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, wantErr: errRLSThrottled, }, { - desc: "cacheMiss_noPending_throttled_defaultTargetOnMiss", - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - throttle: true, - useDefaultPick: true, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_throttled_defaultTargetOnError", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - throttle: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_throttled_clientSeesError", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - throttle: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: errRLSThrottled, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_throttled_defaultTargetOnMiss", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - throttle: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_throttled_defaultTargetOnMiss", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - throttle: true, // Proactive refresh is throttled. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_throttled_clientSeesError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - throttle: true, // Proactive refresh is throttled. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_throttled_defaultTargetOnError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - throttle: true, // Proactive refresh is throttled. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_notThrottled_defaultTargetOnError", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - newRLSRequest: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_notThrottled_clientSeesError", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - newRLSRequest: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, - }, - { - desc: "cacheHit_noPending_boExpired_dataExpired_notThrottled_defaultTargetOnMiss", - cacheEntry: &cache.Entry{}, // Everything is expired in this entry - newRLSRequest: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_notThrottled_defaultTargetOnMiss", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - newRLSRequest: true, // Proactive refresh. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_notThrottled_clientSeesError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - newRLSRequest: true, // Proactive refresh. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boExpired_dataNotExpired_notThrottled_defaultTargetOnError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - newRLSRequest: true, // Proactive refresh. - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boNotExpired_dataExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{BackoffTime: time.Now().Add(defaultTestMaxAge)}, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boNotExpired_dataExpired_defaultTargetOnMiss", - cacheEntry: &cache.Entry{BackoffTime: time.Now().Add(defaultTestMaxAge)}, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boNotExpired_dataExpired_clientSeesError", - cacheEntry: &cache.Entry{ - BackoffTime: time.Now().Add(defaultTestMaxAge), - CallStatus: rlsLastErr, - }, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: rlsLastErr, - }, - { - desc: "cacheHit_noPending_stale_boNotExpired_dataNotExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{ - ExpiryTime: time.Now().Add(defaultTestMaxAge), - BackoffTime: time.Now().Add(defaultTestMaxAge), - CallStatus: rlsLastErr, - }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_noPending_stale_boNotExpired_dataNotExpired_defaultTargetOnMiss", - cacheEntry: &cache.Entry{ - ExpiryTime: time.Now().Add(defaultTestMaxAge), - BackoffTime: time.Now().Add(defaultTestMaxAge), - CallStatus: rlsLastErr, - }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, + desc: "rls request not throttled", + wantRLSRequest: true, + wantErr: balancer.ErrNoSubConnAvailable, }, + } + + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + rlsCh := testutils.NewChannel() + defaultPicker := newFakePicker() + + p := rlsPicker{ + kbm: kbm, + // Cache lookup fails, no pending entry. + readCache: func(key cache.Key) (*cache.Entry, bool) { + if !cmp.Equal(key, wantKey) { + t.Fatalf("cache lookup using cacheKey %v, want %v", key, wantKey) + } + return nil, false + }, + shouldThrottle: func() bool { return test.throttle }, + startRLS: func(path string, km keys.KeyMap) { + if !test.wantRLSRequest { + rlsCh.Send(errors.New("RLS request attempted when none was expected")) + return + } + if path != rpcPath { + rlsCh.Send(fmt.Errorf("RLS request initiated for rpcPath %s, want %s", path, rpcPath)) + return + } + if km.Str != wantKeyMapStr { + rlsCh.Send(fmt.Errorf("RLS request initiated with keys %v, want %v", km.Str, wantKeyMapStr)) + return + } + rlsCh.Send(nil) + }, + } + if test.defaultPickExists { + p.defaultPick = defaultPicker.Pick + } + + gotResult, err := p.Pick(balancer.PickInfo{ + FullMethodName: rpcPath, + Ctx: metadata.NewOutgoingContext(context.Background(), md), + }) + if err != test.wantErr { + t.Fatalf("Pick() returned error {%v}, want {%v}", err, test.wantErr) + } + // If the test specified that a new RLS request should be made, + // verify it. + if test.wantRLSRequest { + if rlsErr, err := rlsCh.Receive(); err != nil || rlsErr != nil { + t.Fatalf("startRLS() = %v, error receiving from channel: %v", rlsErr, err) + } + } + if test.wantErr != nil { + return + } + + // We get here only for cases where we expect the pick to be + // delegated to the default picker. + if err := verifySubConn(gotResult.SubConn, defaultPicker.id); err != nil { + t.Fatal(err) + } + }) + } +} + +// TestPick_DataCacheMiss_PendingCacheMiss verifies different Pick scenarios +// where the entry is not found in the data cache, but there is a entry in the +// pending cache. For all of these scenarios, no new RLS request will be sent. +func TestPick_DataCacheMiss_PendingCacheHit(t *testing.T) { + const ( + rpcPath = "/gFoo/method" + wantKeyMapStr = "k1=v1" + ) + kbm, err := initKeyBuilderMap() + if err != nil { + t.Fatalf("Failed to create keyBuilderMap: %v", err) + } + md := metadata.New(map[string]string{"n1": "v1", "n3": "v3"}) + wantKey := cache.Key{Path: rpcPath, KeyMap: wantKeyMapStr} + + tests := []struct { + desc string + defaultPickExists bool + }{ { - desc: "cacheHit_noPending_stale_boNotExpired_dataNotExpired_clientSeesError", - cacheEntry: &cache.Entry{ - ExpiryTime: time.Now().Add(defaultTestMaxAge), - BackoffTime: time.Now().Add(defaultTestMaxAge), - CallStatus: rlsLastErr, - }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: nil, + desc: "default pick exists", + defaultPickExists: true, }, { - desc: "cacheHit_noPending_notStale_dataNotExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{ - ExpiryTime: time.Now().Add(defaultTestMaxAge), - StaleTime: time.Now().Add(defaultTestMaxAge), - }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, + desc: "default pick does not exists", }, + } + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + rlsCh := testutils.NewChannel() + p := rlsPicker{ + kbm: kbm, + // Cache lookup fails, pending entry exists. + readCache: func(key cache.Key) (*cache.Entry, bool) { + if !cmp.Equal(key, wantKey) { + t.Fatalf("cache lookup using cacheKey %v, want %v", key, wantKey) + } + return nil, true + }, + // Never throttle. We do not expect an RLS request to be sent out anyways. + shouldThrottle: func() bool { return false }, + startRLS: func(_ string, _ keys.KeyMap) { + rlsCh.Send(nil) + }, + } + if test.defaultPickExists { + p.defaultPick = func(info balancer.PickInfo) (balancer.PickResult, error) { + // We do not expect the default picker to be invoked at all. + // So, if we get here, the test will fail, because it + // expects the pick to be queued. + return balancer.PickResult{}, nil + } + } + + if _, err := p.Pick(balancer.PickInfo{ + FullMethodName: rpcPath, + Ctx: metadata.NewOutgoingContext(context.Background(), md), + }); err != balancer.ErrNoSubConnAvailable { + t.Fatalf("Pick() returned error {%v}, want {%v}", err, balancer.ErrNoSubConnAvailable) + } + + // Make sure that no RLS request was sent out. + if _, err := rlsCh.Receive(); err != testutils.ErrRecvTimeout { + t.Fatalf("RLS request sent out when pending entry exists") + } + }) + } +} + +// TestPick_DataCacheHit_PendingCacheMiss verifies different Pick scenarios +// where the entry is found in the data cache, and there is no entry in the +// pending cache. This includes cases where the entry in the data cache is +// stale, expired or in backoff. +func TestPick_DataCacheHit_PendingCacheMiss(t *testing.T) { + const ( + rpcPath = "/gFoo/method" + wantKeyMapStr = "k1=v1" + ) + kbm, err := initKeyBuilderMap() + if err != nil { + t.Fatalf("Failed to create keyBuilderMap: %v", err) + } + md := metadata.New(map[string]string{"n1": "v1", "n3": "v3"}) + wantKey := cache.Key{Path: rpcPath, KeyMap: wantKeyMapStr} + rlsLastErr := errors.New("last RLS request failed") + + tests := []struct { + desc string + // The cache entry, as returned by the overridden readCache hook. + cacheEntry *cache.Entry + // Whether or not a default target is configured. + defaultPickExists bool + // Whether or not the RLS request should be throttled. + throttle bool + // Whether or not the test is expected to make a new RLS request. + wantRLSRequest bool + // Whether or not the rlsPicker should delegate to the child picker. + wantChildPick bool + // Whether or not the rlsPicker should delegate to the default picker. + wantDefaultPick bool + // Expected error returned by the rlsPicker under test. + wantErr error + }{ { - desc: "cacheHit_noPending_notStale_dataNotExpired_defaultTargetOnMiss", + desc: "valid entry", cacheEntry: &cache.Entry{ ExpiryTime: time.Now().Add(defaultTestMaxAge), StaleTime: time.Now().Add(defaultTestMaxAge), }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, + wantChildPick: true, }, { - desc: "cacheHit_noPending_notStale_dataNotExpired_clientSeesError", - cacheEntry: &cache.Entry{ - ExpiryTime: time.Now().Add(defaultTestMaxAge), - StaleTime: time.Now().Add(defaultTestMaxAge), - }, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: nil, + desc: "entryStale_requestThrottled", + cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, + throttle: true, + wantChildPick: true, }, { - desc: "cacheHit_pending_dataExpired_boExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{}, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, + desc: "entryStale_requestNotThrottled", + cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, + wantRLSRequest: true, + wantChildPick: true, }, { - desc: "cacheHit_pending_dataExpired_boExpired_defaultTargetOnMiss", - cacheEntry: &cache.Entry{}, - pending: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, + desc: "entryExpired_requestThrottled_defaultPickExists", + cacheEntry: &cache.Entry{}, + throttle: true, + defaultPickExists: true, + wantDefaultPick: true, }, { - desc: "cacheHit_pending_dataExpired_boExpired_clientSeesError", + desc: "entryExpired_requestThrottled_defaultPickNotExists", cacheEntry: &cache.Entry{}, - pending: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: balancer.ErrNoSubConnAvailable, + throttle: true, + wantErr: errRLSThrottled, }, { - desc: "cacheHit_pending_dataExpired_boNotExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{ - BackoffTime: time.Now().Add(defaultTestMaxAge), - CallStatus: rlsLastErr, - }, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, + desc: "entryExpired_requestNotThrottled", + cacheEntry: &cache.Entry{}, + wantRLSRequest: true, + wantErr: balancer.ErrNoSubConnAvailable, }, { - desc: "cacheHit_pending_dataExpired_boNotExpired_defaultTargetOnMiss", + desc: "entryExpired_backoffNotExpired_defaultPickExists", cacheEntry: &cache.Entry{ BackoffTime: time.Now().Add(defaultTestMaxAge), CallStatus: rlsLastErr, }, - pending: true, - useDefaultPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, + defaultPickExists: true, }, { - desc: "cacheHit_pending_dataExpired_boNotExpired_clientSeesError", + desc: "entryExpired_backoffNotExpired_defaultPickNotExists", cacheEntry: &cache.Entry{ BackoffTime: time.Now().Add(defaultTestMaxAge), CallStatus: rlsLastErr, }, - pending: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: rlsLastErr, - }, - { - desc: "cacheHit_pending_dataNotExpired_defaultTargetOnError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - pending: true, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR, - wantErr: nil, - }, - { - desc: "cacheHit_pending_dataNotExpired_defaultTargetOnMiss", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - pending: true, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS, - wantErr: nil, - }, - { - desc: "cacheHit_pending_dataNotExpired_clientSeesError", - cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, - pending: true, - useChildPick: true, - strategy: rlspb.RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR, - wantErr: nil, + wantErr: rlsLastErr, }, } for _, test := range tests { t.Run(test.desc, func(t *testing.T) { rlsCh := testutils.NewChannel() - randID := grpcrand.Intn(math.MaxInt32) - // We instantiate a fakeChildPicker which will return a fakeSubConn - // with configured id. Either the childPicker or the defaultPicker - // is configured to use this fakePicker based on whether - // useChidlPick or useDefaultPick is set in the test. - childPicker := &fakeChildPicker{id: randID} + childPicker := newFakePicker() + defaultPicker := newFakePicker() p := rlsPicker{ - kbm: kbm, - strategy: test.strategy, + kbm: kbm, readCache: func(key cache.Key) (*cache.Entry, bool) { if !cmp.Equal(key, wantKey) { t.Fatalf("cache lookup using cacheKey %v, want %v", key, wantKey) } - if test.useChildPick { - test.cacheEntry.ChildPicker = childPicker - } - return test.cacheEntry, test.pending + test.cacheEntry.ChildPicker = childPicker + return test.cacheEntry, false }, shouldThrottle: func() bool { return test.throttle }, startRLS: func(path string, km keys.KeyMap) { - if !test.newRLSRequest { + if !test.wantRLSRequest { rlsCh.Send(errors.New("RLS request attempted when none was expected")) return } @@ -536,12 +468,9 @@ func TestPick(t *testing.T) { } rlsCh.Send(nil) }, - defaultPick: func(info balancer.PickInfo) (balancer.PickResult, error) { - if !test.useDefaultPick { - return balancer.PickResult{}, errors.New("Using default pick when the test doesn't want to use default pick") - } - return childPicker.Pick(info) - }, + } + if test.defaultPickExists { + p.defaultPick = defaultPicker.Pick } gotResult, err := p.Pick(balancer.PickInfo{ @@ -551,26 +480,128 @@ func TestPick(t *testing.T) { if err != test.wantErr { t.Fatalf("Pick() returned error {%v}, want {%v}", err, test.wantErr) } - if test.useChildPick || test.useDefaultPick { - // For cases where the pick is not queued, but is delegated to - // either the child rlsPicker or the default rlsPicker, we - // verify that the expected fakeSubConn is returned. - sc, ok := gotResult.SubConn.(*fakeSubConn) - if !ok { - t.Fatalf("Pick() returned a SubConn of type %T, want %T", gotResult.SubConn, &fakeSubConn{}) - } - if sc.id != randID { - t.Fatalf("Pick() returned SubConn %d, want %d", sc.id, randID) - } - } - // If the test specified that a new RLS request should be made, // verify it. - if test.newRLSRequest { + if test.wantRLSRequest { if rlsErr, err := rlsCh.Receive(); err != nil || rlsErr != nil { t.Fatalf("startRLS() = %v, error receiving from channel: %v", rlsErr, err) } } + if test.wantErr != nil { + return + } + + // We get here only for cases where we expect the pick to be + // delegated to the child picker or the default picker. + if test.wantChildPick { + if err := verifySubConn(gotResult.SubConn, childPicker.id); err != nil { + t.Fatal(err) + } + + } + if test.wantDefaultPick { + if err := verifySubConn(gotResult.SubConn, defaultPicker.id); err != nil { + t.Fatal(err) + } + } + }) + } +} + +// TestPick_DataCacheHit_PendingCacheHit verifies different Pick scenarios where +// the entry is found both in the data cache and in the pending cache. This +// mostly verifies cases where the entry is stale, but there is already a +// pending RLS request, so no new request should be sent out. +func TestPick_DataCacheHit_PendingCacheHit(t *testing.T) { + const ( + rpcPath = "/gFoo/method" + wantKeyMapStr = "k1=v1" + ) + kbm, err := initKeyBuilderMap() + if err != nil { + t.Fatalf("Failed to create keyBuilderMap: %v", err) + } + md := metadata.New(map[string]string{"n1": "v1", "n3": "v3"}) + wantKey := cache.Key{Path: rpcPath, KeyMap: wantKeyMapStr} + + tests := []struct { + desc string + // The cache entry, as returned by the overridden readCache hook. + cacheEntry *cache.Entry + // Whether or not a default target is configured. + defaultPickExists bool + // Expected error returned by the rlsPicker under test. + wantErr error + }{ + { + desc: "stale entry", + cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, + }, + { + desc: "stale entry with default picker", + cacheEntry: &cache.Entry{ExpiryTime: time.Now().Add(defaultTestMaxAge)}, + defaultPickExists: true, + }, + { + desc: "entryExpired_defaultPickExists", + cacheEntry: &cache.Entry{}, + defaultPickExists: true, + wantErr: balancer.ErrNoSubConnAvailable, + }, + { + desc: "entryExpired_defaultPickNotExists", + cacheEntry: &cache.Entry{}, + wantErr: balancer.ErrNoSubConnAvailable, + }, + } + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + rlsCh := testutils.NewChannel() + childPicker := newFakePicker() + + p := rlsPicker{ + kbm: kbm, + readCache: func(key cache.Key) (*cache.Entry, bool) { + if !cmp.Equal(key, wantKey) { + t.Fatalf("cache lookup using cacheKey %v, want %v", key, wantKey) + } + test.cacheEntry.ChildPicker = childPicker + return test.cacheEntry, true + }, + // Never throttle. We do not expect an RLS request to be sent out anyways. + shouldThrottle: func() bool { return false }, + startRLS: func(path string, km keys.KeyMap) { + rlsCh.Send(nil) + }, + } + if test.defaultPickExists { + p.defaultPick = func(info balancer.PickInfo) (balancer.PickResult, error) { + // We do not expect the default picker to be invoked at all. + // So, if we get here, we return an error. + return balancer.PickResult{}, errors.New("default picker invoked when expecting a child pick") + } + } + + gotResult, err := p.Pick(balancer.PickInfo{ + FullMethodName: rpcPath, + Ctx: metadata.NewOutgoingContext(context.Background(), md), + }) + if err != test.wantErr { + t.Fatalf("Pick() returned error {%v}, want {%v}", err, test.wantErr) + } + // Make sure that no RLS request was sent out. + if _, err := rlsCh.Receive(); err != testutils.ErrRecvTimeout { + t.Fatalf("RLS request sent out when pending entry exists") + } + if test.wantErr != nil { + return + } + + // We get here only for cases where we expect the pick to be + // delegated to the child picker. + if err := verifySubConn(gotResult.SubConn, childPicker.id); err != nil { + t.Fatal(err) + } }) } } diff --git a/balancer/rls/internal/proto/grpc_lookup_v1/rls_config.pb.go b/balancer/rls/internal/proto/grpc_lookup_v1/rls_config.pb.go index 88479f41e397..01d5b656ebe2 100644 --- a/balancer/rls/internal/proto/grpc_lookup_v1/rls_config.pb.go +++ b/balancer/rls/internal/proto/grpc_lookup_v1/rls_config.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc/rls/grpc_lookup_v1/rls_config.proto +// source: grpc/lookup/v1/rls_config.proto package grpc_lookup_v1 @@ -21,51 +21,6 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -// Specify how to process a request when not already in the cache. -type RouteLookupConfig_RequestProcessingStrategy int32 - -const ( - RouteLookupConfig_STRATEGY_UNSPECIFIED RouteLookupConfig_RequestProcessingStrategy = 0 - // Query the RLS and process the request using target returned by the - // lookup. The target will then be cached and used for processing - // subsequent requests for the same key. Any errors during lookup service - // processing will fall back to default target for request processing. - RouteLookupConfig_SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR RouteLookupConfig_RequestProcessingStrategy = 1 - // Query the RLS and process the request using target returned by the - // lookup. The target will then be cached and used for processing - // subsequent requests for the same key. Any errors during lookup service - // processing will return an error back to the client. Services with - // strict regional routing requirements should use this strategy. - RouteLookupConfig_SYNC_LOOKUP_CLIENT_SEES_ERROR RouteLookupConfig_RequestProcessingStrategy = 2 - // Query the RLS asynchronously but respond with the default target. The - // target in the lookup response will then be cached and used for - // subsequent requests. Services with strict latency requirements (but not - // strict regional routing requirements) should use this strategy. - RouteLookupConfig_ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS RouteLookupConfig_RequestProcessingStrategy = 3 -) - -var RouteLookupConfig_RequestProcessingStrategy_name = map[int32]string{ - 0: "STRATEGY_UNSPECIFIED", - 1: "SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR", - 2: "SYNC_LOOKUP_CLIENT_SEES_ERROR", - 3: "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS", -} - -var RouteLookupConfig_RequestProcessingStrategy_value = map[string]int32{ - "STRATEGY_UNSPECIFIED": 0, - "SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR": 1, - "SYNC_LOOKUP_CLIENT_SEES_ERROR": 2, - "ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS": 3, -} - -func (x RouteLookupConfig_RequestProcessingStrategy) String() string { - return proto.EnumName(RouteLookupConfig_RequestProcessingStrategy_name, int32(x)) -} - -func (RouteLookupConfig_RequestProcessingStrategy) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{3, 0} -} - // Extract a key based on a given name (e.g. header name or query parameter // name). The name must match one of the names listed in the "name" field. If // the "required_match" field is true, one of the specified names must be @@ -88,7 +43,7 @@ func (m *NameMatcher) Reset() { *m = NameMatcher{} } func (m *NameMatcher) String() string { return proto.CompactTextString(m) } func (*NameMatcher) ProtoMessage() {} func (*NameMatcher) Descriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{0} + return fileDescriptor_5fe74d4f6e8f01c1, []int{0} } func (m *NameMatcher) XXX_Unmarshal(b []byte) error { @@ -146,7 +101,7 @@ func (m *GrpcKeyBuilder) Reset() { *m = GrpcKeyBuilder{} } func (m *GrpcKeyBuilder) String() string { return proto.CompactTextString(m) } func (*GrpcKeyBuilder) ProtoMessage() {} func (*GrpcKeyBuilder) Descriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{1} + return fileDescriptor_5fe74d4f6e8f01c1, []int{1} } func (m *GrpcKeyBuilder) XXX_Unmarshal(b []byte) error { @@ -197,7 +152,7 @@ func (m *GrpcKeyBuilder_Name) Reset() { *m = GrpcKeyBuilder_Name{} } func (m *GrpcKeyBuilder_Name) String() string { return proto.CompactTextString(m) } func (*GrpcKeyBuilder_Name) ProtoMessage() {} func (*GrpcKeyBuilder_Name) Descriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{1, 0} + return fileDescriptor_5fe74d4f6e8f01c1, []int{1, 0} } func (m *GrpcKeyBuilder_Name) XXX_Unmarshal(b []byte) error { @@ -311,7 +266,7 @@ func (m *HttpKeyBuilder) Reset() { *m = HttpKeyBuilder{} } func (m *HttpKeyBuilder) String() string { return proto.CompactTextString(m) } func (*HttpKeyBuilder) ProtoMessage() {} func (*HttpKeyBuilder) Descriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{2} + return fileDescriptor_5fe74d4f6e8f01c1, []int{2} } func (m *HttpKeyBuilder) XXX_Unmarshal(b []byte) error { @@ -396,27 +351,23 @@ type RouteLookupConfig struct { CacheSizeBytes int64 `protobuf:"varint,7,opt,name=cache_size_bytes,json=cacheSizeBytes,proto3" json:"cache_size_bytes,omitempty"` // This is a list of all the possible targets that can be returned by the // lookup service. If a target not on this list is returned, it will be - // treated the same as an RPC error from the RLS. + // treated the same as an unhealthy target. ValidTargets []string `protobuf:"bytes,8,rep,name=valid_targets,json=validTargets,proto3" json:"valid_targets,omitempty"` - // This value provides a default target to use if needed. It will be used for - // request processing strategy SYNC_LOOKUP_DEFAULT_TARGET_ON_ERROR if RLS - // returns an error, or strategy ASYNC_LOOKUP_DEFAULT_TARGET_ON_MISS if RLS - // returns an error or there is a cache miss in the client. It will also be - // used if there are no healthy backends for an RLS target. Note that - // requests can be routed only to a subdomain of the original target, - // e.g. "us_east_1.cloudbigtable.googleapis.com". - DefaultTarget string `protobuf:"bytes,9,opt,name=default_target,json=defaultTarget,proto3" json:"default_target,omitempty"` - RequestProcessingStrategy RouteLookupConfig_RequestProcessingStrategy `protobuf:"varint,10,opt,name=request_processing_strategy,json=requestProcessingStrategy,proto3,enum=grpc.lookup.v1.RouteLookupConfig_RequestProcessingStrategy" json:"request_processing_strategy,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + // This value provides a default target to use if needed. If set, it will be + // used if RLS returns an error, times out, or returns an invalid response. + // Note that requests can be routed only to a subdomain of the original + // target, e.g. "us_east_1.cloudbigtable.googleapis.com". + DefaultTarget string `protobuf:"bytes,9,opt,name=default_target,json=defaultTarget,proto3" json:"default_target,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RouteLookupConfig) Reset() { *m = RouteLookupConfig{} } func (m *RouteLookupConfig) String() string { return proto.CompactTextString(m) } func (*RouteLookupConfig) ProtoMessage() {} func (*RouteLookupConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_f013e3228551a7a8, []int{3} + return fileDescriptor_5fe74d4f6e8f01c1, []int{3} } func (m *RouteLookupConfig) XXX_Unmarshal(b []byte) error { @@ -500,15 +451,7 @@ func (m *RouteLookupConfig) GetDefaultTarget() string { return "" } -func (m *RouteLookupConfig) GetRequestProcessingStrategy() RouteLookupConfig_RequestProcessingStrategy { - if m != nil { - return m.RequestProcessingStrategy - } - return RouteLookupConfig_STRATEGY_UNSPECIFIED -} - func init() { - proto.RegisterEnum("grpc.lookup.v1.RouteLookupConfig_RequestProcessingStrategy", RouteLookupConfig_RequestProcessingStrategy_name, RouteLookupConfig_RequestProcessingStrategy_value) proto.RegisterType((*NameMatcher)(nil), "grpc.lookup.v1.NameMatcher") proto.RegisterType((*GrpcKeyBuilder)(nil), "grpc.lookup.v1.GrpcKeyBuilder") proto.RegisterType((*GrpcKeyBuilder_Name)(nil), "grpc.lookup.v1.GrpcKeyBuilder.Name") @@ -516,57 +459,47 @@ func init() { proto.RegisterType((*RouteLookupConfig)(nil), "grpc.lookup.v1.RouteLookupConfig") } -func init() { - proto.RegisterFile("grpc/rls/grpc_lookup_v1/rls_config.proto", fileDescriptor_f013e3228551a7a8) -} - -var fileDescriptor_f013e3228551a7a8 = []byte{ - // 742 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xdd, 0x6e, 0xdb, 0x36, - 0x18, 0x9d, 0xa2, 0xd4, 0x89, 0x99, 0x46, 0x71, 0x85, 0xa0, 0x50, 0x5a, 0xac, 0xf0, 0x1c, 0x14, - 0xd3, 0xc5, 0x20, 0xa3, 0x1e, 0x36, 0x6c, 0xd8, 0x95, 0xed, 0x28, 0x99, 0x51, 0xd7, 0x36, 0x28, - 0xe5, 0xa2, 0xc3, 0x00, 0x82, 0x96, 0xbf, 0x48, 0x42, 0x24, 0x53, 0xa5, 0x28, 0xa3, 0xee, 0xde, - 0x68, 0xc0, 0xde, 0x60, 0x2f, 0xb2, 0xb7, 0x19, 0x28, 0x4a, 0x9e, 0xed, 0x2d, 0x4b, 0xef, 0xf4, - 0x1d, 0x9e, 0x73, 0xc4, 0xef, 0x8f, 0xc8, 0x0e, 0x79, 0x16, 0x74, 0x79, 0x92, 0x77, 0xe5, 0x07, - 0x49, 0x18, 0xbb, 0x2f, 0x32, 0xb2, 0x7a, 0x23, 0x21, 0x12, 0xb0, 0xe5, 0x5d, 0x1c, 0x3a, 0x19, - 0x67, 0x82, 0x99, 0x86, 0x24, 0x38, 0x8a, 0xe0, 0xac, 0xde, 0xbc, 0x78, 0x15, 0x32, 0x16, 0x26, - 0xd0, 0x2d, 0x4f, 0xe7, 0xc5, 0x5d, 0x77, 0x51, 0x70, 0x2a, 0x62, 0xb6, 0x54, 0xfc, 0xce, 0xaf, - 0xe8, 0x64, 0x42, 0x53, 0x78, 0x47, 0x45, 0x10, 0x01, 0x37, 0x5b, 0x48, 0xbf, 0x87, 0xb5, 0xa5, - 0xb5, 0x35, 0xbb, 0x89, 0xe5, 0xa7, 0x79, 0x8e, 0x9e, 0x2c, 0x69, 0x0a, 0xb9, 0x75, 0xd0, 0xd6, - 0xed, 0x26, 0x56, 0x81, 0xf9, 0x1a, 0x19, 0x1c, 0x3e, 0x14, 0x31, 0x87, 0x05, 0x49, 0xa5, 0xd6, - 0xd2, 0xdb, 0x9a, 0x7d, 0x8c, 0x4f, 0x6b, 0xb4, 0x34, 0xec, 0xfc, 0xa9, 0x21, 0xe3, 0x86, 0x67, - 0xc1, 0x5b, 0x58, 0x0f, 0x8a, 0x38, 0x59, 0x00, 0x37, 0x7f, 0xac, 0xfd, 0xb4, 0xb6, 0x6e, 0x9f, - 0xf4, 0x2e, 0x9d, 0xdd, 0x0b, 0x3b, 0xbb, 0x74, 0x47, 0x5e, 0xae, 0xfe, 0xe9, 0x77, 0xe8, 0x28, - 0x02, 0xba, 0x00, 0xae, 0x2e, 0x73, 0xd2, 0x7b, 0xb9, 0x2f, 0xde, 0x4a, 0x05, 0xd7, 0xdc, 0x17, - 0x3f, 0xa0, 0x43, 0x89, 0x9b, 0x16, 0x3a, 0xca, 0x81, 0xaf, 0xe2, 0x00, 0xaa, 0xfc, 0xea, 0xd0, - 0x7c, 0x8e, 0x1a, 0x29, 0x88, 0x88, 0x2d, 0xac, 0x83, 0xf2, 0xa0, 0x8a, 0x3a, 0x7f, 0x69, 0xc8, - 0xf8, 0x59, 0x88, 0x6c, 0xeb, 0xfa, 0x97, 0xe8, 0x34, 0x62, 0xb9, 0x20, 0x19, 0x15, 0x02, 0xf8, - 0x52, 0xa5, 0xd1, 0xc4, 0x4f, 0x25, 0x38, 0xab, 0x30, 0x49, 0xca, 0xa8, 0x88, 0xfe, 0x21, 0xa9, - 0xda, 0x3d, 0x95, 0xe0, 0x86, 0x74, 0x8d, 0x5a, 0x1f, 0x0a, 0xe0, 0x6b, 0x92, 0x51, 0x4e, 0x53, - 0x10, 0x32, 0x2d, 0xfd, 0xf1, 0xb4, 0xce, 0x4a, 0xd1, 0x6c, 0xa3, 0xd9, 0xae, 0xca, 0xe1, 0xe7, - 0x57, 0xa5, 0xf3, 0x47, 0x03, 0x3d, 0xc3, 0xac, 0x10, 0x30, 0x2e, 0x79, 0xc3, 0x72, 0x88, 0xcc, - 0x11, 0x6a, 0x45, 0x42, 0x64, 0xe4, 0x1e, 0xd6, 0x73, 0x95, 0x71, 0xdd, 0xa8, 0x57, 0xfb, 0xae, - 0xbb, 0x85, 0xc1, 0x67, 0x91, 0x8a, 0x6b, 0x99, 0xb4, 0x2a, 0x87, 0x75, 0xdb, 0xea, 0xe0, 0xbf, - 0xad, 0x76, 0x7b, 0x8e, 0xcf, 0x42, 0x15, 0x6f, 0xac, 0x5e, 0x23, 0xa3, 0x1a, 0xf9, 0xba, 0x81, - 0x7a, 0xd9, 0xa7, 0x53, 0x85, 0x7a, 0x55, 0x1b, 0xa7, 0xe8, 0xf9, 0x2e, 0x8d, 0x88, 0x38, 0x05, - 0x56, 0x08, 0xeb, 0xb0, 0xad, 0xd9, 0x27, 0xbd, 0x0b, 0x47, 0x2d, 0x83, 0x53, 0x2f, 0x83, 0x73, - 0x55, 0x2d, 0x03, 0x3e, 0xdf, 0x71, 0xf2, 0x95, 0xcc, 0xec, 0xa1, 0xa3, 0x94, 0x7e, 0x24, 0x34, - 0x04, 0xeb, 0xc9, 0x63, 0x0e, 0x8d, 0x94, 0x7e, 0xec, 0x87, 0x60, 0x7e, 0x8f, 0x9a, 0xb9, 0xa0, - 0x09, 0x94, 0xaa, 0xc6, 0x63, 0xaa, 0xe3, 0x92, 0x2b, 0x75, 0x36, 0x6a, 0x05, 0x34, 0x88, 0x80, - 0xe4, 0xf1, 0x27, 0x20, 0xf3, 0xb5, 0x80, 0xdc, 0x3a, 0x6a, 0x6b, 0xb6, 0x8e, 0x8d, 0x12, 0xf7, - 0xe2, 0x4f, 0x30, 0x90, 0xa8, 0x9c, 0xae, 0x15, 0x4d, 0xe2, 0x05, 0x11, 0x94, 0x87, 0x20, 0x72, - 0xeb, 0x58, 0x4d, 0x57, 0x09, 0xfa, 0x0a, 0x93, 0x25, 0x5b, 0xc0, 0x1d, 0x2d, 0x12, 0x51, 0xd1, - 0xac, 0xa6, 0x2a, 0x59, 0x85, 0x2a, 0x9e, 0xf9, 0x1b, 0x7a, 0x29, 0x37, 0x16, 0xe4, 0x44, 0x73, - 0x16, 0x40, 0x9e, 0xc7, 0xcb, 0x90, 0xe4, 0x82, 0x53, 0x01, 0xe1, 0xda, 0x42, 0x6d, 0xcd, 0x36, - 0x7a, 0x3f, 0xed, 0xf7, 0xeb, 0x5f, 0x73, 0xe3, 0x60, 0x65, 0x32, 0xdb, 0x78, 0x78, 0x95, 0x05, - 0xbe, 0xe0, 0x0f, 0x1d, 0x75, 0x7e, 0xd7, 0xd0, 0xc5, 0x83, 0x42, 0xd3, 0x42, 0xe7, 0x9e, 0x8f, - 0xfb, 0xbe, 0x7b, 0xf3, 0x9e, 0xdc, 0x4e, 0xbc, 0x99, 0x3b, 0x1c, 0x5d, 0x8f, 0xdc, 0xab, 0xd6, - 0x17, 0xe6, 0xd7, 0xe8, 0xd2, 0x7b, 0x3f, 0x19, 0x92, 0xf1, 0x74, 0xfa, 0xf6, 0x76, 0x46, 0xae, - 0xdc, 0xeb, 0xfe, 0xed, 0xd8, 0x27, 0x7e, 0x1f, 0xdf, 0xb8, 0x3e, 0x99, 0x4e, 0x88, 0x8b, 0xf1, - 0x14, 0xb7, 0x34, 0xf3, 0x2b, 0xf4, 0xe5, 0x36, 0x71, 0x38, 0x1e, 0xb9, 0x13, 0x9f, 0x78, 0xae, - 0xeb, 0x55, 0x94, 0x03, 0xe9, 0xd5, 0xff, 0x7f, 0xb3, 0x77, 0x23, 0xcf, 0x6b, 0xe9, 0x03, 0x0f, - 0x3d, 0x8b, 0xd9, 0x5e, 0x21, 0x06, 0x06, 0x4e, 0x72, 0x55, 0x81, 0x99, 0x6c, 0xed, 0x4c, 0xfb, - 0xe5, 0x9b, 0xaa, 0xd5, 0x21, 0x4b, 0xe8, 0x32, 0x74, 0x18, 0x0f, 0xcb, 0x27, 0xbb, 0xab, 0x34, - 0x7b, 0xcf, 0xf7, 0xbc, 0x51, 0x4e, 0xc4, 0xb7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x47, 0xa7, - 0x94, 0xbe, 0xe0, 0x05, 0x00, 0x00, +func init() { proto.RegisterFile("grpc/lookup/v1/rls_config.proto", fileDescriptor_5fe74d4f6e8f01c1) } + +var fileDescriptor_5fe74d4f6e8f01c1 = []byte{ + // 615 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xed, 0x6a, 0xdb, 0x30, + 0x14, 0xc5, 0x75, 0x9a, 0x0f, 0xa5, 0x75, 0x53, 0x53, 0x8a, 0xd7, 0x42, 0x17, 0x52, 0x0a, 0xfe, + 0x31, 0x1c, 0x9a, 0xb1, 0xb1, 0xfd, 0x5c, 0x36, 0xf6, 0xfd, 0x11, 0xdc, 0xfe, 0x1a, 0x03, 0xa1, + 0xd8, 0xb7, 0xb2, 0xa9, 0x1d, 0xb9, 0x92, 0x1c, 0x9a, 0x3e, 0xd0, 0x9e, 0x62, 0x2f, 0xb2, 0xb7, + 0x19, 0x92, 0xec, 0x2e, 0x2e, 0x83, 0xec, 0x5f, 0xee, 0xd1, 0x39, 0x27, 0x3a, 0xf7, 0x5e, 0x19, + 0x3d, 0xa6, 0xbc, 0x88, 0xc6, 0x19, 0x63, 0xd7, 0x65, 0x31, 0x5e, 0x9e, 0x8f, 0x79, 0x26, 0x70, + 0xc4, 0x16, 0x57, 0x29, 0x0d, 0x0a, 0xce, 0x24, 0x73, 0x1d, 0x45, 0x08, 0x0c, 0x21, 0x58, 0x9e, + 0x1f, 0x9d, 0x50, 0xc6, 0x68, 0x06, 0x63, 0x7d, 0x3a, 0x2f, 0xaf, 0xc6, 0x71, 0xc9, 0x89, 0x4c, + 0xd9, 0xc2, 0xf0, 0x47, 0x3f, 0x50, 0xff, 0x2b, 0xc9, 0xe1, 0x0b, 0x91, 0x51, 0x02, 0xdc, 0x1d, + 0x20, 0xfb, 0x1a, 0x56, 0x9e, 0x35, 0xb4, 0xfc, 0x5e, 0xa8, 0x7e, 0xba, 0x07, 0x68, 0x7b, 0x41, + 0x72, 0x10, 0xde, 0xd6, 0xd0, 0xf6, 0x7b, 0xa1, 0x29, 0xdc, 0x33, 0xe4, 0x70, 0xb8, 0x29, 0x53, + 0x0e, 0x31, 0xce, 0x95, 0xd6, 0xb3, 0x87, 0x96, 0xdf, 0x0d, 0x77, 0x6b, 0x54, 0x1b, 0x8e, 0x7e, + 0x59, 0xc8, 0x79, 0xc7, 0x8b, 0xe8, 0x13, 0xac, 0xa6, 0x65, 0x9a, 0xc5, 0xc0, 0xdd, 0x97, 0xb5, + 0x9f, 0x35, 0xb4, 0xfd, 0xfe, 0xe4, 0x34, 0x68, 0x5e, 0x38, 0x68, 0xd2, 0x03, 0x75, 0xb9, 0xfa, + 0x4f, 0x9f, 0xa1, 0x4e, 0x02, 0x24, 0x06, 0x6e, 0x2e, 0xd3, 0x9f, 0x1c, 0x3f, 0x14, 0xaf, 0x45, + 0x09, 0x6b, 0xee, 0xd1, 0x0b, 0xd4, 0x52, 0xb8, 0xeb, 0xa1, 0x8e, 0x00, 0xbe, 0x4c, 0x23, 0xa8, + 0xf2, 0xd5, 0xa5, 0x7b, 0x88, 0xda, 0x39, 0xc8, 0x84, 0xc5, 0xde, 0x96, 0x3e, 0xa8, 0xaa, 0xd1, + 0x6f, 0x0b, 0x39, 0xef, 0xa5, 0x2c, 0xd6, 0xae, 0x7f, 0x8a, 0x76, 0x13, 0x26, 0x24, 0x2e, 0x88, + 0x94, 0xc0, 0x17, 0x26, 0x46, 0x2f, 0xdc, 0x51, 0xe0, 0xac, 0xc2, 0x14, 0xa9, 0x20, 0x32, 0xf9, + 0x4b, 0x32, 0xbd, 0xdb, 0x51, 0xe0, 0x3d, 0xe9, 0x2d, 0x1a, 0xdc, 0x94, 0xc0, 0x57, 0xb8, 0x20, + 0x9c, 0xe4, 0x20, 0x55, 0x2c, 0x7b, 0x73, 0xac, 0x3d, 0x2d, 0x9a, 0xdd, 0x6b, 0xd6, 0xbb, 0xd2, + 0xfa, 0xff, 0xae, 0x8c, 0x7e, 0xb6, 0xd0, 0x7e, 0xc8, 0x4a, 0x09, 0x9f, 0x35, 0xef, 0xb5, 0x5e, + 0x22, 0xf7, 0x03, 0x1a, 0x24, 0x52, 0x16, 0xf8, 0x1a, 0x56, 0x73, 0x93, 0xb8, 0x1e, 0xd4, 0xc9, + 0x43, 0xd7, 0x66, 0x63, 0xc2, 0xbd, 0xc4, 0xd4, 0xb5, 0x4c, 0x59, 0x29, 0x45, 0xc3, 0x6a, 0xeb, + 0xdf, 0x56, 0xcd, 0x99, 0x87, 0x7b, 0xd4, 0xd4, 0xf7, 0x56, 0x67, 0xc8, 0x31, 0x64, 0x5c, 0x0f, + 0xd0, 0xd6, 0x73, 0xda, 0x35, 0xe8, 0x45, 0x35, 0xc6, 0x6f, 0xe8, 0xb0, 0x49, 0xc3, 0x32, 0xcd, + 0x81, 0x95, 0xd2, 0x6b, 0x0d, 0x2d, 0xbf, 0x3f, 0x79, 0x14, 0x98, 0xc7, 0x10, 0xd4, 0x8f, 0x21, + 0x78, 0x53, 0x3d, 0x86, 0xf0, 0xa0, 0xe1, 0x74, 0x69, 0x64, 0xee, 0x04, 0x75, 0x72, 0x72, 0x8b, + 0x09, 0x05, 0x6f, 0x7b, 0x93, 0x43, 0x3b, 0x27, 0xb7, 0xaf, 0x28, 0xb8, 0xcf, 0x51, 0x4f, 0x48, + 0x92, 0x81, 0x56, 0xb5, 0x37, 0xa9, 0xba, 0x9a, 0xab, 0x74, 0x3e, 0x1a, 0x44, 0x24, 0x4a, 0x00, + 0x8b, 0xf4, 0x0e, 0xf0, 0x7c, 0x25, 0x41, 0x78, 0x9d, 0xa1, 0xe5, 0xdb, 0xa1, 0xa3, 0xf1, 0x8b, + 0xf4, 0x0e, 0xa6, 0x0a, 0x55, 0xdb, 0xb5, 0x24, 0x59, 0x1a, 0x63, 0x49, 0x38, 0x05, 0x29, 0xbc, + 0xae, 0xd9, 0x2e, 0x0d, 0x5e, 0x1a, 0x4c, 0xb5, 0x2c, 0x86, 0x2b, 0x52, 0x66, 0xb2, 0xa2, 0x79, + 0x3d, 0xd3, 0xb2, 0x0a, 0x35, 0xbc, 0x8f, 0xad, 0x2e, 0x1a, 0xf4, 0xc3, 0x63, 0xf5, 0x6a, 0x41, + 0x6d, 0x35, 0x67, 0x11, 0x08, 0x91, 0x2e, 0x28, 0x16, 0x92, 0x13, 0x09, 0x74, 0x35, 0xbd, 0x40, + 0xfb, 0x29, 0x7b, 0x30, 0xb1, 0xa9, 0x13, 0x66, 0xc2, 0xac, 0xcc, 0x4c, 0x65, 0x9a, 0x59, 0xdf, + 0x9f, 0x54, 0x19, 0x29, 0xcb, 0xc8, 0x82, 0x06, 0x8c, 0xd3, 0xf1, 0xfa, 0xb7, 0x4a, 0xaf, 0x42, + 0x35, 0x9d, 0xe5, 0xf9, 0xbc, 0xad, 0x5b, 0xf1, 0xf4, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xaa, 0xbd, 0xb2, 0xd0, 0x04, 0x00, 0x00, } diff --git a/regenerate.sh b/regenerate.sh index cb7e5b61beb0..7e33b45e0862 100755 --- a/regenerate.sh +++ b/regenerate.sh @@ -69,6 +69,7 @@ SOURCES=( ${WORKDIR}/grpc-proto/grpc/health/v1/health.proto ${WORKDIR}/grpc-proto/grpc/lb/v1/load_balancer.proto ${WORKDIR}/grpc-proto/grpc/lookup/v1/rls.proto + ${WORKDIR}/grpc-proto/grpc/lookup/v1/rls_config.proto ${WORKDIR}/grpc-proto/grpc/service_config/service_config.proto ${WORKDIR}/grpc-proto/grpc/tls/provider/meshca/experimental/config.proto ${WORKDIR}/istio/istio/google/security/meshca/v1/meshca.proto