diff --git a/internal/proto/grpc_service_config/build.go b/internal/proto/grpc_service_config/build.go new file mode 100644 index 000000000000..241e554861a1 --- /dev/null +++ b/internal/proto/grpc_service_config/build.go @@ -0,0 +1,23 @@ +/* + * + * 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. + * + */ + +//go:generate ./regenerate.sh + +// Package grpc_service_config provides generated code for service config. +// It's only used for tests. +package grpc_service_config diff --git a/internal/proto/grpc_service_config/example_test.go b/internal/proto/grpc_service_config/example_test.go new file mode 100644 index 000000000000..956fbef745da --- /dev/null +++ b/internal/proto/grpc_service_config/example_test.go @@ -0,0 +1,57 @@ +/* + * + * 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 grpc_service_config_test + +import ( + "testing" + + "github.com/golang/protobuf/jsonpb" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + scpb "google.golang.org/grpc/internal/proto/grpc_service_config" +) + +// TestExampleMarshalToJSON is an example to print json format of xds_config. +func TestXdsConfigMarshalToJSON(t *testing.T) { + c := &scpb.XdsConfig{ + ChildPolicy: []*scpb.LoadBalancingConfig{ + {Policy: &scpb.LoadBalancingConfig_Grpclb{ + Grpclb: &scpb.GrpcLbConfig{}, + }}, + {Policy: &scpb.LoadBalancingConfig_RoundRobin{ + RoundRobin: &scpb.RoundRobinConfig{}, + }}, + }, + FallbackPolicy: []*scpb.LoadBalancingConfig{ + {Policy: &scpb.LoadBalancingConfig_Grpclb{ + Grpclb: &scpb.GrpcLbConfig{}, + }}, + {Policy: &scpb.LoadBalancingConfig_PickFirst{ + PickFirst: &scpb.PickFirstConfig{}, + }}, + }, + EdsServiceName: "eds.service.name", + LrsLoadReportingServerName: &wrapperspb.StringValue{ + Value: "lrs.server.name", + }, + } + j, err := (&jsonpb.Marshaler{}).MarshalToString(c) + if err != nil { + t.Fatalf("failed to marshal proto to json: %v", err) + } + t.Logf(j) +} diff --git a/internal/proto/grpc_service_config/regenerate.sh b/internal/proto/grpc_service_config/regenerate.sh new file mode 100755 index 000000000000..b67a25c36461 --- /dev/null +++ b/internal/proto/grpc_service_config/regenerate.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# 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. + +set -eux -o pipefail + +TMP=$(mktemp -d) + +function finish { + rm -rf "$TMP" +} +trap finish EXIT + +pushd "$TMP" +mkdir -p grpc/service_config +curl https://raw.githubusercontent.com/grpc/grpc-proto/master/grpc/service_config/service_config.proto > grpc/service_config/service_config.proto +mkdir -p google/rpc +curl https://raw.githubusercontent.com/googleapis/googleapis/master/google/rpc/code.proto > google/rpc/code.proto + +protoc --go_out=plugins=grpc,paths=source_relative:. -I. grpc/service_config/*.proto +popd +rm -f ./*.pb.go +cp "$TMP"/grpc/service_config/*.pb.go ./ + diff --git a/internal/proto/grpc_service_config/service_config.pb.go b/internal/proto/grpc_service_config/service_config.pb.go new file mode 100644 index 000000000000..0f78df0f50a0 --- /dev/null +++ b/internal/proto/grpc_service_config/service_config.pb.go @@ -0,0 +1,1131 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: grpc/service_config/service_config.proto + +package grpc_service_config + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + duration "github.com/golang/protobuf/ptypes/duration" + wrappers "github.com/golang/protobuf/ptypes/wrappers" + code "google.golang.org/genproto/googleapis/rpc/code" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Load balancing policy. +// +// Note that load_balancing_policy is deprecated in favor of +// load_balancing_config; the former will be used only if the latter +// is unset. +// +// If no LB policy is configured here, then the default is pick_first. +// If the policy name is set via the client API, that value overrides +// the value specified here. +// +// If the deprecated load_balancing_policy field is used, note that if the +// resolver returns at least one balancer address (as opposed to backend +// addresses), gRPC will use grpclb (see +// https://github.com/grpc/grpc/blob/master/doc/load-balancing.md), +// regardless of what policy is configured here. However, if the resolver +// returns at least one backend address in addition to the balancer +// address(es), the client may fall back to the requested policy if it +// is unable to reach any of the grpclb load balancers. +type ServiceConfig_LoadBalancingPolicy int32 + +const ( + ServiceConfig_UNSPECIFIED ServiceConfig_LoadBalancingPolicy = 0 + ServiceConfig_ROUND_ROBIN ServiceConfig_LoadBalancingPolicy = 1 +) + +var ServiceConfig_LoadBalancingPolicy_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "ROUND_ROBIN", +} + +var ServiceConfig_LoadBalancingPolicy_value = map[string]int32{ + "UNSPECIFIED": 0, + "ROUND_ROBIN": 1, +} + +func (x ServiceConfig_LoadBalancingPolicy) String() string { + return proto.EnumName(ServiceConfig_LoadBalancingPolicy_name, int32(x)) +} + +func (ServiceConfig_LoadBalancingPolicy) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{7, 0} +} + +// Configuration for a method. +type MethodConfig struct { + Name []*MethodConfig_Name `protobuf:"bytes,1,rep,name=name,proto3" json:"name,omitempty"` + // Whether RPCs sent to this method should wait until the connection is + // ready by default. If false, the RPC will abort immediately if there is + // a transient failure connecting to the server. Otherwise, gRPC will + // attempt to connect until the deadline is exceeded. + // + // The value specified via the gRPC client API will override the value + // set here. However, note that setting the value in the client API will + // also affect transient errors encountered during name resolution, which + // cannot be caught by the value here, since the service config is + // obtained by the gRPC client via name resolution. + WaitForReady *wrappers.BoolValue `protobuf:"bytes,2,opt,name=wait_for_ready,json=waitForReady,proto3" json:"wait_for_ready,omitempty"` + // The default timeout in seconds for RPCs sent to this method. This can be + // overridden in code. If no reply is received in the specified amount of + // time, the request is aborted and a DEADLINE_EXCEEDED error status + // is returned to the caller. + // + // The actual deadline used will be the minimum of the value specified here + // and the value set by the application via the gRPC client API. If either + // one is not set, then the other will be used. If neither is set, then the + // request has no deadline. + Timeout *duration.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"` + // The maximum allowed payload size for an individual request or object in a + // stream (client->server) in bytes. The size which is measured is the + // serialized payload after per-message compression (but before stream + // compression) in bytes. This applies both to streaming and non-streaming + // requests. + // + // The actual value used is the minumum of the value specified here and the + // value set by the application via the gRPC client API. If either one is + // not set, then the other will be used. If neither is set, then the + // built-in default is used. + // + // If a client attempts to send an object larger than this value, it will not + // be sent and the client will see a ClientError. + // Note that 0 is a valid value, meaning that the request message + // must be empty. + MaxRequestMessageBytes *wrappers.UInt32Value `protobuf:"bytes,4,opt,name=max_request_message_bytes,json=maxRequestMessageBytes,proto3" json:"max_request_message_bytes,omitempty"` + // The maximum allowed payload size for an individual response or object in a + // stream (server->client) in bytes. The size which is measured is the + // serialized payload after per-message compression (but before stream + // compression) in bytes. This applies both to streaming and non-streaming + // requests. + // + // The actual value used is the minumum of the value specified here and the + // value set by the application via the gRPC client API. If either one is + // not set, then the other will be used. If neither is set, then the + // built-in default is used. + // + // If a server attempts to send an object larger than this value, it will not + // be sent, and a ServerError will be sent to the client instead. + // Note that 0 is a valid value, meaning that the response message + // must be empty. + MaxResponseMessageBytes *wrappers.UInt32Value `protobuf:"bytes,5,opt,name=max_response_message_bytes,json=maxResponseMessageBytes,proto3" json:"max_response_message_bytes,omitempty"` + // Only one of retry_policy or hedging_policy may be set. If neither is set, + // RPCs will not be retried or hedged. + // + // Types that are valid to be assigned to RetryOrHedgingPolicy: + // *MethodConfig_RetryPolicy_ + // *MethodConfig_HedgingPolicy_ + RetryOrHedgingPolicy isMethodConfig_RetryOrHedgingPolicy `protobuf_oneof:"retry_or_hedging_policy"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodConfig) Reset() { *m = MethodConfig{} } +func (m *MethodConfig) String() string { return proto.CompactTextString(m) } +func (*MethodConfig) ProtoMessage() {} +func (*MethodConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{0} +} + +func (m *MethodConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodConfig.Unmarshal(m, b) +} +func (m *MethodConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodConfig.Marshal(b, m, deterministic) +} +func (m *MethodConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodConfig.Merge(m, src) +} +func (m *MethodConfig) XXX_Size() int { + return xxx_messageInfo_MethodConfig.Size(m) +} +func (m *MethodConfig) XXX_DiscardUnknown() { + xxx_messageInfo_MethodConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodConfig proto.InternalMessageInfo + +func (m *MethodConfig) GetName() []*MethodConfig_Name { + if m != nil { + return m.Name + } + return nil +} + +func (m *MethodConfig) GetWaitForReady() *wrappers.BoolValue { + if m != nil { + return m.WaitForReady + } + return nil +} + +func (m *MethodConfig) GetTimeout() *duration.Duration { + if m != nil { + return m.Timeout + } + return nil +} + +func (m *MethodConfig) GetMaxRequestMessageBytes() *wrappers.UInt32Value { + if m != nil { + return m.MaxRequestMessageBytes + } + return nil +} + +func (m *MethodConfig) GetMaxResponseMessageBytes() *wrappers.UInt32Value { + if m != nil { + return m.MaxResponseMessageBytes + } + return nil +} + +type isMethodConfig_RetryOrHedgingPolicy interface { + isMethodConfig_RetryOrHedgingPolicy() +} + +type MethodConfig_RetryPolicy_ struct { + RetryPolicy *MethodConfig_RetryPolicy `protobuf:"bytes,6,opt,name=retry_policy,json=retryPolicy,proto3,oneof"` +} + +type MethodConfig_HedgingPolicy_ struct { + HedgingPolicy *MethodConfig_HedgingPolicy `protobuf:"bytes,7,opt,name=hedging_policy,json=hedgingPolicy,proto3,oneof"` +} + +func (*MethodConfig_RetryPolicy_) isMethodConfig_RetryOrHedgingPolicy() {} + +func (*MethodConfig_HedgingPolicy_) isMethodConfig_RetryOrHedgingPolicy() {} + +func (m *MethodConfig) GetRetryOrHedgingPolicy() isMethodConfig_RetryOrHedgingPolicy { + if m != nil { + return m.RetryOrHedgingPolicy + } + return nil +} + +func (m *MethodConfig) GetRetryPolicy() *MethodConfig_RetryPolicy { + if x, ok := m.GetRetryOrHedgingPolicy().(*MethodConfig_RetryPolicy_); ok { + return x.RetryPolicy + } + return nil +} + +func (m *MethodConfig) GetHedgingPolicy() *MethodConfig_HedgingPolicy { + if x, ok := m.GetRetryOrHedgingPolicy().(*MethodConfig_HedgingPolicy_); ok { + return x.HedgingPolicy + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*MethodConfig) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*MethodConfig_RetryPolicy_)(nil), + (*MethodConfig_HedgingPolicy_)(nil), + } +} + +// The names of the methods to which this configuration applies. There must +// be at least one name. Each name entry must be unique across the entire +// ClientConfig. If the 'method' field is empty, then this MethodConfig +// specifies the defaults for all methods for the specified service. +// +// For example, let's say that the service config contains the following +// MethodConfig entries: +// +// method_config { name { service: "MyService" } ... } +// method_config { name { service: "MyService" method: "Foo" } ... } +// +// For a request for MyService/Foo, we will use the second entry, because it +// exactly matches the service and method name. +// For a request for MyService/Bar, we will use the first entry, because it +// provides the default for all methods of MyService. +type MethodConfig_Name struct { + Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` + Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodConfig_Name) Reset() { *m = MethodConfig_Name{} } +func (m *MethodConfig_Name) String() string { return proto.CompactTextString(m) } +func (*MethodConfig_Name) ProtoMessage() {} +func (*MethodConfig_Name) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{0, 0} +} + +func (m *MethodConfig_Name) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodConfig_Name.Unmarshal(m, b) +} +func (m *MethodConfig_Name) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodConfig_Name.Marshal(b, m, deterministic) +} +func (m *MethodConfig_Name) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodConfig_Name.Merge(m, src) +} +func (m *MethodConfig_Name) XXX_Size() int { + return xxx_messageInfo_MethodConfig_Name.Size(m) +} +func (m *MethodConfig_Name) XXX_DiscardUnknown() { + xxx_messageInfo_MethodConfig_Name.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodConfig_Name proto.InternalMessageInfo + +func (m *MethodConfig_Name) GetService() string { + if m != nil { + return m.Service + } + return "" +} + +func (m *MethodConfig_Name) GetMethod() string { + if m != nil { + return m.Method + } + return "" +} + +// The retry policy for outgoing RPCs. +type MethodConfig_RetryPolicy struct { + // The maximum number of RPC attempts, including the original attempt. + // + // This field is required and must be greater than 1. + // Any value greater than 5 will be treated as if it were 5. + MaxAttempts uint32 `protobuf:"varint,1,opt,name=max_attempts,json=maxAttempts,proto3" json:"max_attempts,omitempty"` + // Exponential backoff parameters. The initial retry attempt will occur at + // random(0, initial_backoff). In general, the nth attempt will occur at + // random(0, + // min(initial_backoff*backoff_multiplier**(n-1), max_backoff)). + // Required. Must be greater than zero. + InitialBackoff *duration.Duration `protobuf:"bytes,2,opt,name=initial_backoff,json=initialBackoff,proto3" json:"initial_backoff,omitempty"` + // Required. Must be greater than zero. + MaxBackoff *duration.Duration `protobuf:"bytes,3,opt,name=max_backoff,json=maxBackoff,proto3" json:"max_backoff,omitempty"` + BackoffMultiplier float32 `protobuf:"fixed32,4,opt,name=backoff_multiplier,json=backoffMultiplier,proto3" json:"backoff_multiplier,omitempty"` + // The set of status codes which may be retried. + // + // This field is required and must be non-empty. + RetryableStatusCodes []code.Code `protobuf:"varint,5,rep,packed,name=retryable_status_codes,json=retryableStatusCodes,proto3,enum=google.rpc.Code" json:"retryable_status_codes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodConfig_RetryPolicy) Reset() { *m = MethodConfig_RetryPolicy{} } +func (m *MethodConfig_RetryPolicy) String() string { return proto.CompactTextString(m) } +func (*MethodConfig_RetryPolicy) ProtoMessage() {} +func (*MethodConfig_RetryPolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{0, 1} +} + +func (m *MethodConfig_RetryPolicy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodConfig_RetryPolicy.Unmarshal(m, b) +} +func (m *MethodConfig_RetryPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodConfig_RetryPolicy.Marshal(b, m, deterministic) +} +func (m *MethodConfig_RetryPolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodConfig_RetryPolicy.Merge(m, src) +} +func (m *MethodConfig_RetryPolicy) XXX_Size() int { + return xxx_messageInfo_MethodConfig_RetryPolicy.Size(m) +} +func (m *MethodConfig_RetryPolicy) XXX_DiscardUnknown() { + xxx_messageInfo_MethodConfig_RetryPolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodConfig_RetryPolicy proto.InternalMessageInfo + +func (m *MethodConfig_RetryPolicy) GetMaxAttempts() uint32 { + if m != nil { + return m.MaxAttempts + } + return 0 +} + +func (m *MethodConfig_RetryPolicy) GetInitialBackoff() *duration.Duration { + if m != nil { + return m.InitialBackoff + } + return nil +} + +func (m *MethodConfig_RetryPolicy) GetMaxBackoff() *duration.Duration { + if m != nil { + return m.MaxBackoff + } + return nil +} + +func (m *MethodConfig_RetryPolicy) GetBackoffMultiplier() float32 { + if m != nil { + return m.BackoffMultiplier + } + return 0 +} + +func (m *MethodConfig_RetryPolicy) GetRetryableStatusCodes() []code.Code { + if m != nil { + return m.RetryableStatusCodes + } + return nil +} + +// The hedging policy for outgoing RPCs. Hedged RPCs may execute more than +// once on the server, so only idempotent methods should specify a hedging +// policy. +type MethodConfig_HedgingPolicy struct { + // The hedging policy will send up to max_requests RPCs. + // This number represents the total number of all attempts, including + // the original attempt. + // + // This field is required and must be greater than 1. + // Any value greater than 5 will be treated as if it were 5. + MaxAttempts uint32 `protobuf:"varint,1,opt,name=max_attempts,json=maxAttempts,proto3" json:"max_attempts,omitempty"` + // The first RPC will be sent immediately, but the max_requests-1 subsequent + // hedged RPCs will be sent at intervals of every hedging_delay. Set this + // to 0 to immediately send all max_requests RPCs. + HedgingDelay *duration.Duration `protobuf:"bytes,2,opt,name=hedging_delay,json=hedgingDelay,proto3" json:"hedging_delay,omitempty"` + // The set of status codes which indicate other hedged RPCs may still + // succeed. If a non-fatal status code is returned by the server, hedged + // RPCs will continue. Otherwise, outstanding requests will be canceled and + // the error returned to the client application layer. + // + // This field is optional. + NonFatalStatusCodes []code.Code `protobuf:"varint,3,rep,packed,name=non_fatal_status_codes,json=nonFatalStatusCodes,proto3,enum=google.rpc.Code" json:"non_fatal_status_codes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MethodConfig_HedgingPolicy) Reset() { *m = MethodConfig_HedgingPolicy{} } +func (m *MethodConfig_HedgingPolicy) String() string { return proto.CompactTextString(m) } +func (*MethodConfig_HedgingPolicy) ProtoMessage() {} +func (*MethodConfig_HedgingPolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{0, 2} +} + +func (m *MethodConfig_HedgingPolicy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MethodConfig_HedgingPolicy.Unmarshal(m, b) +} +func (m *MethodConfig_HedgingPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MethodConfig_HedgingPolicy.Marshal(b, m, deterministic) +} +func (m *MethodConfig_HedgingPolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_MethodConfig_HedgingPolicy.Merge(m, src) +} +func (m *MethodConfig_HedgingPolicy) XXX_Size() int { + return xxx_messageInfo_MethodConfig_HedgingPolicy.Size(m) +} +func (m *MethodConfig_HedgingPolicy) XXX_DiscardUnknown() { + xxx_messageInfo_MethodConfig_HedgingPolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_MethodConfig_HedgingPolicy proto.InternalMessageInfo + +func (m *MethodConfig_HedgingPolicy) GetMaxAttempts() uint32 { + if m != nil { + return m.MaxAttempts + } + return 0 +} + +func (m *MethodConfig_HedgingPolicy) GetHedgingDelay() *duration.Duration { + if m != nil { + return m.HedgingDelay + } + return nil +} + +func (m *MethodConfig_HedgingPolicy) GetNonFatalStatusCodes() []code.Code { + if m != nil { + return m.NonFatalStatusCodes + } + return nil +} + +// Configuration for pick_first LB policy. +type PickFirstConfig struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PickFirstConfig) Reset() { *m = PickFirstConfig{} } +func (m *PickFirstConfig) String() string { return proto.CompactTextString(m) } +func (*PickFirstConfig) ProtoMessage() {} +func (*PickFirstConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{1} +} + +func (m *PickFirstConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PickFirstConfig.Unmarshal(m, b) +} +func (m *PickFirstConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PickFirstConfig.Marshal(b, m, deterministic) +} +func (m *PickFirstConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_PickFirstConfig.Merge(m, src) +} +func (m *PickFirstConfig) XXX_Size() int { + return xxx_messageInfo_PickFirstConfig.Size(m) +} +func (m *PickFirstConfig) XXX_DiscardUnknown() { + xxx_messageInfo_PickFirstConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_PickFirstConfig proto.InternalMessageInfo + +// Configuration for round_robin LB policy. +type RoundRobinConfig struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RoundRobinConfig) Reset() { *m = RoundRobinConfig{} } +func (m *RoundRobinConfig) String() string { return proto.CompactTextString(m) } +func (*RoundRobinConfig) ProtoMessage() {} +func (*RoundRobinConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{2} +} + +func (m *RoundRobinConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RoundRobinConfig.Unmarshal(m, b) +} +func (m *RoundRobinConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RoundRobinConfig.Marshal(b, m, deterministic) +} +func (m *RoundRobinConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_RoundRobinConfig.Merge(m, src) +} +func (m *RoundRobinConfig) XXX_Size() int { + return xxx_messageInfo_RoundRobinConfig.Size(m) +} +func (m *RoundRobinConfig) XXX_DiscardUnknown() { + xxx_messageInfo_RoundRobinConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_RoundRobinConfig proto.InternalMessageInfo + +// Configuration for grpclb LB policy. +type GrpcLbConfig struct { + // Optional. What LB policy to use for routing between the backend + // addresses. If unset, defaults to round_robin. + // Currently, the only supported values are round_robin and pick_first. + // Note that this will be used both in balancer mode and in fallback mode. + // Multiple LB policies can be specified; clients will iterate through + // the list in order and stop at the first policy that they support. + ChildPolicy []*LoadBalancingConfig `protobuf:"bytes,1,rep,name=child_policy,json=childPolicy,proto3" json:"child_policy,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GrpcLbConfig) Reset() { *m = GrpcLbConfig{} } +func (m *GrpcLbConfig) String() string { return proto.CompactTextString(m) } +func (*GrpcLbConfig) ProtoMessage() {} +func (*GrpcLbConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{3} +} + +func (m *GrpcLbConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GrpcLbConfig.Unmarshal(m, b) +} +func (m *GrpcLbConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GrpcLbConfig.Marshal(b, m, deterministic) +} +func (m *GrpcLbConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_GrpcLbConfig.Merge(m, src) +} +func (m *GrpcLbConfig) XXX_Size() int { + return xxx_messageInfo_GrpcLbConfig.Size(m) +} +func (m *GrpcLbConfig) XXX_DiscardUnknown() { + xxx_messageInfo_GrpcLbConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_GrpcLbConfig proto.InternalMessageInfo + +func (m *GrpcLbConfig) GetChildPolicy() []*LoadBalancingConfig { + if m != nil { + return m.ChildPolicy + } + return nil +} + +// Configuration for the cds LB policy. +type CdsConfig struct { + Cluster string `protobuf:"bytes,1,opt,name=cluster,proto3" json:"cluster,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CdsConfig) Reset() { *m = CdsConfig{} } +func (m *CdsConfig) String() string { return proto.CompactTextString(m) } +func (*CdsConfig) ProtoMessage() {} +func (*CdsConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{4} +} + +func (m *CdsConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CdsConfig.Unmarshal(m, b) +} +func (m *CdsConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CdsConfig.Marshal(b, m, deterministic) +} +func (m *CdsConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_CdsConfig.Merge(m, src) +} +func (m *CdsConfig) XXX_Size() int { + return xxx_messageInfo_CdsConfig.Size(m) +} +func (m *CdsConfig) XXX_DiscardUnknown() { + xxx_messageInfo_CdsConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_CdsConfig proto.InternalMessageInfo + +func (m *CdsConfig) GetCluster() string { + if m != nil { + return m.Cluster + } + return "" +} + +// Configuration for xds LB policy. +type XdsConfig struct { + // Name of balancer to connect to. + BalancerName string `protobuf:"bytes,1,opt,name=balancer_name,json=balancerName,proto3" json:"balancer_name,omitempty"` // Deprecated: Do not use. + // Optional. What LB policy to use for intra-locality routing. + // If unset, will use whatever algorithm is specified by the balancer. + // Multiple LB policies can be specified; clients will iterate through + // the list in order and stop at the first policy that they support. + ChildPolicy []*LoadBalancingConfig `protobuf:"bytes,2,rep,name=child_policy,json=childPolicy,proto3" json:"child_policy,omitempty"` + // Optional. What LB policy to use in fallback mode. If not + // specified, defaults to round_robin. + // Multiple LB policies can be specified; clients will iterate through + // the list in order and stop at the first policy that they support. + FallbackPolicy []*LoadBalancingConfig `protobuf:"bytes,3,rep,name=fallback_policy,json=fallbackPolicy,proto3" json:"fallback_policy,omitempty"` + // Optional. Name to use in EDS query. If not present, defaults to + // the server name from the target URI. + EdsServiceName string `protobuf:"bytes,4,opt,name=eds_service_name,json=edsServiceName,proto3" json:"eds_service_name,omitempty"` + // LRS server to send load reports to. + // If not present, load reporting will be disabled. + // If set to the empty string, load reporting will be sent to the same + // server that we obtained CDS data from. + LrsLoadReportingServerName *wrappers.StringValue `protobuf:"bytes,5,opt,name=lrs_load_reporting_server_name,json=lrsLoadReportingServerName,proto3" json:"lrs_load_reporting_server_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *XdsConfig) Reset() { *m = XdsConfig{} } +func (m *XdsConfig) String() string { return proto.CompactTextString(m) } +func (*XdsConfig) ProtoMessage() {} +func (*XdsConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{5} +} + +func (m *XdsConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_XdsConfig.Unmarshal(m, b) +} +func (m *XdsConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_XdsConfig.Marshal(b, m, deterministic) +} +func (m *XdsConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_XdsConfig.Merge(m, src) +} +func (m *XdsConfig) XXX_Size() int { + return xxx_messageInfo_XdsConfig.Size(m) +} +func (m *XdsConfig) XXX_DiscardUnknown() { + xxx_messageInfo_XdsConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_XdsConfig proto.InternalMessageInfo + +// Deprecated: Do not use. +func (m *XdsConfig) GetBalancerName() string { + if m != nil { + return m.BalancerName + } + return "" +} + +func (m *XdsConfig) GetChildPolicy() []*LoadBalancingConfig { + if m != nil { + return m.ChildPolicy + } + return nil +} + +func (m *XdsConfig) GetFallbackPolicy() []*LoadBalancingConfig { + if m != nil { + return m.FallbackPolicy + } + return nil +} + +func (m *XdsConfig) GetEdsServiceName() string { + if m != nil { + return m.EdsServiceName + } + return "" +} + +func (m *XdsConfig) GetLrsLoadReportingServerName() *wrappers.StringValue { + if m != nil { + return m.LrsLoadReportingServerName + } + return nil +} + +// Selects LB policy and provides corresponding configuration. +// +// In general, all instances of this field should be repeated. +// Clients will iterate through the list in order and stop at the first +// policy that they support. This allows the service config to specify +// custom policies that may not be known to all clients. +type LoadBalancingConfig struct { + // Exactly one LB policy may be configured. + // + // Types that are valid to be assigned to Policy: + // *LoadBalancingConfig_PickFirst + // *LoadBalancingConfig_RoundRobin + // *LoadBalancingConfig_Grpclb + // *LoadBalancingConfig_Cds + // *LoadBalancingConfig_Xds + // *LoadBalancingConfig_XdsExperimental + Policy isLoadBalancingConfig_Policy `protobuf_oneof:"policy"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LoadBalancingConfig) Reset() { *m = LoadBalancingConfig{} } +func (m *LoadBalancingConfig) String() string { return proto.CompactTextString(m) } +func (*LoadBalancingConfig) ProtoMessage() {} +func (*LoadBalancingConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{6} +} + +func (m *LoadBalancingConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LoadBalancingConfig.Unmarshal(m, b) +} +func (m *LoadBalancingConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LoadBalancingConfig.Marshal(b, m, deterministic) +} +func (m *LoadBalancingConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_LoadBalancingConfig.Merge(m, src) +} +func (m *LoadBalancingConfig) XXX_Size() int { + return xxx_messageInfo_LoadBalancingConfig.Size(m) +} +func (m *LoadBalancingConfig) XXX_DiscardUnknown() { + xxx_messageInfo_LoadBalancingConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_LoadBalancingConfig proto.InternalMessageInfo + +type isLoadBalancingConfig_Policy interface { + isLoadBalancingConfig_Policy() +} + +type LoadBalancingConfig_PickFirst struct { + PickFirst *PickFirstConfig `protobuf:"bytes,4,opt,name=pick_first,proto3,oneof"` +} + +type LoadBalancingConfig_RoundRobin struct { + RoundRobin *RoundRobinConfig `protobuf:"bytes,1,opt,name=round_robin,proto3,oneof"` +} + +type LoadBalancingConfig_Grpclb struct { + Grpclb *GrpcLbConfig `protobuf:"bytes,3,opt,name=grpclb,proto3,oneof"` +} + +type LoadBalancingConfig_Cds struct { + Cds *CdsConfig `protobuf:"bytes,6,opt,name=cds,proto3,oneof"` +} + +type LoadBalancingConfig_Xds struct { + Xds *XdsConfig `protobuf:"bytes,2,opt,name=xds,proto3,oneof"` +} + +type LoadBalancingConfig_XdsExperimental struct { + XdsExperimental *XdsConfig `protobuf:"bytes,5,opt,name=xds_experimental,proto3,oneof"` +} + +func (*LoadBalancingConfig_PickFirst) isLoadBalancingConfig_Policy() {} + +func (*LoadBalancingConfig_RoundRobin) isLoadBalancingConfig_Policy() {} + +func (*LoadBalancingConfig_Grpclb) isLoadBalancingConfig_Policy() {} + +func (*LoadBalancingConfig_Cds) isLoadBalancingConfig_Policy() {} + +func (*LoadBalancingConfig_Xds) isLoadBalancingConfig_Policy() {} + +func (*LoadBalancingConfig_XdsExperimental) isLoadBalancingConfig_Policy() {} + +func (m *LoadBalancingConfig) GetPolicy() isLoadBalancingConfig_Policy { + if m != nil { + return m.Policy + } + return nil +} + +func (m *LoadBalancingConfig) GetPickFirst() *PickFirstConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_PickFirst); ok { + return x.PickFirst + } + return nil +} + +func (m *LoadBalancingConfig) GetRoundRobin() *RoundRobinConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_RoundRobin); ok { + return x.RoundRobin + } + return nil +} + +func (m *LoadBalancingConfig) GetGrpclb() *GrpcLbConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_Grpclb); ok { + return x.Grpclb + } + return nil +} + +func (m *LoadBalancingConfig) GetCds() *CdsConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_Cds); ok { + return x.Cds + } + return nil +} + +func (m *LoadBalancingConfig) GetXds() *XdsConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_Xds); ok { + return x.Xds + } + return nil +} + +func (m *LoadBalancingConfig) GetXdsExperimental() *XdsConfig { + if x, ok := m.GetPolicy().(*LoadBalancingConfig_XdsExperimental); ok { + return x.XdsExperimental + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*LoadBalancingConfig) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*LoadBalancingConfig_PickFirst)(nil), + (*LoadBalancingConfig_RoundRobin)(nil), + (*LoadBalancingConfig_Grpclb)(nil), + (*LoadBalancingConfig_Cds)(nil), + (*LoadBalancingConfig_Xds)(nil), + (*LoadBalancingConfig_XdsExperimental)(nil), + } +} + +// A ServiceConfig represents information about a service but is not specific to +// any name resolver. +type ServiceConfig struct { + LoadBalancingPolicy ServiceConfig_LoadBalancingPolicy `protobuf:"varint,1,opt,name=load_balancing_policy,json=loadBalancingPolicy,proto3,enum=grpc.service_config.ServiceConfig_LoadBalancingPolicy" json:"load_balancing_policy,omitempty"` // Deprecated: Do not use. + // Multiple LB policies can be specified; clients will iterate through + // the list in order and stop at the first policy that they support. If none + // are supported, the service config is considered invalid. + LoadBalancingConfig []*LoadBalancingConfig `protobuf:"bytes,4,rep,name=load_balancing_config,json=loadBalancingConfig,proto3" json:"load_balancing_config,omitempty"` + // Per-method configuration. + MethodConfig []*MethodConfig `protobuf:"bytes,2,rep,name=method_config,json=methodConfig,proto3" json:"method_config,omitempty"` + RetryThrottling *ServiceConfig_RetryThrottlingPolicy `protobuf:"bytes,3,opt,name=retry_throttling,json=retryThrottling,proto3" json:"retry_throttling,omitempty"` + HealthCheckConfig *ServiceConfig_HealthCheckConfig `protobuf:"bytes,5,opt,name=health_check_config,json=healthCheckConfig,proto3" json:"health_check_config,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceConfig) Reset() { *m = ServiceConfig{} } +func (m *ServiceConfig) String() string { return proto.CompactTextString(m) } +func (*ServiceConfig) ProtoMessage() {} +func (*ServiceConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{7} +} + +func (m *ServiceConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceConfig.Unmarshal(m, b) +} +func (m *ServiceConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceConfig.Marshal(b, m, deterministic) +} +func (m *ServiceConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceConfig.Merge(m, src) +} +func (m *ServiceConfig) XXX_Size() int { + return xxx_messageInfo_ServiceConfig.Size(m) +} +func (m *ServiceConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceConfig proto.InternalMessageInfo + +// Deprecated: Do not use. +func (m *ServiceConfig) GetLoadBalancingPolicy() ServiceConfig_LoadBalancingPolicy { + if m != nil { + return m.LoadBalancingPolicy + } + return ServiceConfig_UNSPECIFIED +} + +func (m *ServiceConfig) GetLoadBalancingConfig() []*LoadBalancingConfig { + if m != nil { + return m.LoadBalancingConfig + } + return nil +} + +func (m *ServiceConfig) GetMethodConfig() []*MethodConfig { + if m != nil { + return m.MethodConfig + } + return nil +} + +func (m *ServiceConfig) GetRetryThrottling() *ServiceConfig_RetryThrottlingPolicy { + if m != nil { + return m.RetryThrottling + } + return nil +} + +func (m *ServiceConfig) GetHealthCheckConfig() *ServiceConfig_HealthCheckConfig { + if m != nil { + return m.HealthCheckConfig + } + return nil +} + +// If a RetryThrottlingPolicy is provided, gRPC will automatically throttle +// retry attempts and hedged RPCs when the client's ratio of failures to +// successes exceeds a threshold. +// +// For each server name, the gRPC client will maintain a token_count which is +// initially set to max_tokens. Every outgoing RPC (regardless of service or +// method invoked) will change token_count as follows: +// +// - Every failed RPC will decrement the token_count by 1. +// - Every successful RPC will increment the token_count by token_ratio. +// +// If token_count is less than or equal to max_tokens / 2, then RPCs will not +// be retried and hedged RPCs will not be sent. +type ServiceConfig_RetryThrottlingPolicy struct { + // The number of tokens starts at max_tokens. The token_count will always be + // between 0 and max_tokens. + // + // This field is required and must be greater than zero. + MaxTokens uint32 `protobuf:"varint,1,opt,name=max_tokens,json=maxTokens,proto3" json:"max_tokens,omitempty"` + // The amount of tokens to add on each successful RPC. Typically this will + // be some number between 0 and 1, e.g., 0.1. + // + // This field is required and must be greater than zero. Up to 3 decimal + // places are supported. + TokenRatio float32 `protobuf:"fixed32,2,opt,name=token_ratio,json=tokenRatio,proto3" json:"token_ratio,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceConfig_RetryThrottlingPolicy) Reset() { *m = ServiceConfig_RetryThrottlingPolicy{} } +func (m *ServiceConfig_RetryThrottlingPolicy) String() string { return proto.CompactTextString(m) } +func (*ServiceConfig_RetryThrottlingPolicy) ProtoMessage() {} +func (*ServiceConfig_RetryThrottlingPolicy) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{7, 0} +} + +func (m *ServiceConfig_RetryThrottlingPolicy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy.Unmarshal(m, b) +} +func (m *ServiceConfig_RetryThrottlingPolicy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy.Marshal(b, m, deterministic) +} +func (m *ServiceConfig_RetryThrottlingPolicy) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy.Merge(m, src) +} +func (m *ServiceConfig_RetryThrottlingPolicy) XXX_Size() int { + return xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy.Size(m) +} +func (m *ServiceConfig_RetryThrottlingPolicy) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceConfig_RetryThrottlingPolicy proto.InternalMessageInfo + +func (m *ServiceConfig_RetryThrottlingPolicy) GetMaxTokens() uint32 { + if m != nil { + return m.MaxTokens + } + return 0 +} + +func (m *ServiceConfig_RetryThrottlingPolicy) GetTokenRatio() float32 { + if m != nil { + return m.TokenRatio + } + return 0 +} + +type ServiceConfig_HealthCheckConfig struct { + // Service name to use in the health-checking request. + ServiceName *wrappers.StringValue `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ServiceConfig_HealthCheckConfig) Reset() { *m = ServiceConfig_HealthCheckConfig{} } +func (m *ServiceConfig_HealthCheckConfig) String() string { return proto.CompactTextString(m) } +func (*ServiceConfig_HealthCheckConfig) ProtoMessage() {} +func (*ServiceConfig_HealthCheckConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_e32d3cb2c41c77ce, []int{7, 1} +} + +func (m *ServiceConfig_HealthCheckConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ServiceConfig_HealthCheckConfig.Unmarshal(m, b) +} +func (m *ServiceConfig_HealthCheckConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ServiceConfig_HealthCheckConfig.Marshal(b, m, deterministic) +} +func (m *ServiceConfig_HealthCheckConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServiceConfig_HealthCheckConfig.Merge(m, src) +} +func (m *ServiceConfig_HealthCheckConfig) XXX_Size() int { + return xxx_messageInfo_ServiceConfig_HealthCheckConfig.Size(m) +} +func (m *ServiceConfig_HealthCheckConfig) XXX_DiscardUnknown() { + xxx_messageInfo_ServiceConfig_HealthCheckConfig.DiscardUnknown(m) +} + +var xxx_messageInfo_ServiceConfig_HealthCheckConfig proto.InternalMessageInfo + +func (m *ServiceConfig_HealthCheckConfig) GetServiceName() *wrappers.StringValue { + if m != nil { + return m.ServiceName + } + return nil +} + +func init() { + proto.RegisterEnum("grpc.service_config.ServiceConfig_LoadBalancingPolicy", ServiceConfig_LoadBalancingPolicy_name, ServiceConfig_LoadBalancingPolicy_value) + proto.RegisterType((*MethodConfig)(nil), "grpc.service_config.MethodConfig") + proto.RegisterType((*MethodConfig_Name)(nil), "grpc.service_config.MethodConfig.Name") + proto.RegisterType((*MethodConfig_RetryPolicy)(nil), "grpc.service_config.MethodConfig.RetryPolicy") + proto.RegisterType((*MethodConfig_HedgingPolicy)(nil), "grpc.service_config.MethodConfig.HedgingPolicy") + proto.RegisterType((*PickFirstConfig)(nil), "grpc.service_config.PickFirstConfig") + proto.RegisterType((*RoundRobinConfig)(nil), "grpc.service_config.RoundRobinConfig") + proto.RegisterType((*GrpcLbConfig)(nil), "grpc.service_config.GrpcLbConfig") + proto.RegisterType((*CdsConfig)(nil), "grpc.service_config.CdsConfig") + proto.RegisterType((*XdsConfig)(nil), "grpc.service_config.XdsConfig") + proto.RegisterType((*LoadBalancingConfig)(nil), "grpc.service_config.LoadBalancingConfig") + proto.RegisterType((*ServiceConfig)(nil), "grpc.service_config.ServiceConfig") + proto.RegisterType((*ServiceConfig_RetryThrottlingPolicy)(nil), "grpc.service_config.ServiceConfig.RetryThrottlingPolicy") + proto.RegisterType((*ServiceConfig_HealthCheckConfig)(nil), "grpc.service_config.ServiceConfig.HealthCheckConfig") +} + +func init() { + proto.RegisterFile("grpc/service_config/service_config.proto", fileDescriptor_e32d3cb2c41c77ce) +} + +var fileDescriptor_e32d3cb2c41c77ce = []byte{ + // 1155 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xed, 0x6e, 0x1b, 0x45, + 0x14, 0x8d, 0xed, 0x34, 0xa9, 0xaf, 0x3f, 0xe2, 0x4c, 0x48, 0xea, 0x5a, 0x50, 0x5a, 0x8b, 0x82, + 0xff, 0xd4, 0x91, 0x5c, 0x04, 0x55, 0x91, 0xf8, 0x70, 0x52, 0xe3, 0x88, 0x36, 0x0d, 0x93, 0x96, + 0x16, 0x81, 0x34, 0x8c, 0x77, 0xc7, 0xf6, 0x2a, 0xbb, 0x3b, 0xcb, 0xcc, 0x98, 0x3a, 0x0f, 0x84, + 0x78, 0x06, 0xde, 0x84, 0x5f, 0x88, 0x47, 0x41, 0xf3, 0xb1, 0x8e, 0xd7, 0x76, 0x71, 0x2a, 0x7e, + 0xee, 0x9d, 0x7b, 0xce, 0x9c, 0xb9, 0xf7, 0xcc, 0x9d, 0x85, 0xd6, 0x48, 0x24, 0xde, 0xa1, 0x64, + 0xe2, 0xb7, 0xc0, 0x63, 0xc4, 0xe3, 0xf1, 0x30, 0x18, 0x2d, 0x7c, 0xb6, 0x13, 0xc1, 0x15, 0x47, + 0x7b, 0x3a, 0xb3, 0x9d, 0x5d, 0x6a, 0xdc, 0x19, 0x71, 0x3e, 0x0a, 0xd9, 0xa1, 0x49, 0x19, 0x4c, + 0x86, 0x87, 0xfe, 0x44, 0x50, 0x15, 0xf0, 0xd8, 0x82, 0x96, 0xd7, 0xdf, 0x08, 0x9a, 0x24, 0x4c, + 0x48, 0xb7, 0xbe, 0xef, 0xd6, 0xb5, 0x08, 0x8f, 0xfb, 0xcc, 0x86, 0x9b, 0x7f, 0xdf, 0x84, 0xf2, + 0x33, 0xa6, 0xc6, 0xdc, 0x3f, 0x32, 0xfb, 0xa0, 0xc7, 0xb0, 0x19, 0xd3, 0x88, 0xd5, 0x73, 0x77, + 0x0b, 0xad, 0x52, 0xe7, 0xe3, 0xf6, 0x0a, 0x2d, 0xed, 0x79, 0x40, 0xfb, 0x94, 0x46, 0x0c, 0x1b, + 0x0c, 0xfa, 0x1a, 0xaa, 0x6f, 0x68, 0xa0, 0xc8, 0x90, 0x0b, 0x22, 0x18, 0xf5, 0x2f, 0xeb, 0xf9, + 0xbb, 0xb9, 0x56, 0xa9, 0xd3, 0x68, 0xdb, 0xcd, 0xdb, 0xa9, 0xb8, 0x76, 0x97, 0xf3, 0xf0, 0x07, + 0x1a, 0x4e, 0x18, 0x2e, 0x6b, 0x44, 0x8f, 0x0b, 0xac, 0xf3, 0xd1, 0x43, 0xd8, 0x56, 0x41, 0xc4, + 0xf8, 0x44, 0xd5, 0x0b, 0x06, 0x7a, 0x7b, 0x09, 0x7a, 0xec, 0xce, 0x8d, 0xd3, 0x4c, 0xf4, 0x0a, + 0x6e, 0x47, 0x74, 0x4a, 0x04, 0xfb, 0x75, 0xc2, 0xa4, 0x22, 0x11, 0x93, 0x92, 0x8e, 0x18, 0x19, + 0x5c, 0x2a, 0x26, 0xeb, 0x9b, 0x86, 0xe6, 0xfd, 0x25, 0x9a, 0x97, 0x27, 0xb1, 0x7a, 0xd8, 0xb1, + 0x1a, 0x0e, 0x22, 0x3a, 0xc5, 0x16, 0xfd, 0xcc, 0x82, 0xbb, 0x1a, 0x8b, 0x7e, 0x84, 0x86, 0x25, + 0x96, 0x09, 0x8f, 0x25, 0x5b, 0x60, 0xbe, 0x71, 0x0d, 0xe6, 0x5b, 0x86, 0xd9, 0xc2, 0x33, 0xd4, + 0x18, 0xca, 0x82, 0x29, 0x71, 0x49, 0x12, 0x1e, 0x06, 0xde, 0x65, 0x7d, 0xcb, 0x90, 0x3d, 0x58, + 0x5f, 0x6e, 0xac, 0x51, 0x67, 0x06, 0xd4, 0xdf, 0xc0, 0x25, 0x71, 0xf5, 0x89, 0x5e, 0x43, 0x75, + 0xcc, 0xfc, 0x51, 0x10, 0x8f, 0x52, 0xd6, 0x6d, 0xc3, 0x7a, 0xb8, 0x9e, 0xb5, 0x6f, 0x71, 0x33, + 0xde, 0xca, 0x78, 0x3e, 0xd0, 0x78, 0x04, 0x9b, 0xba, 0xcd, 0xa8, 0x0e, 0xdb, 0x8e, 0xa5, 0x9e, + 0xbb, 0x9b, 0x6b, 0x15, 0x71, 0xfa, 0x89, 0x0e, 0x60, 0x2b, 0x32, 0x84, 0xa6, 0xe5, 0x45, 0xec, + 0xbe, 0x1a, 0x7f, 0xe4, 0xa1, 0x34, 0x27, 0x19, 0xdd, 0x83, 0xb2, 0x2e, 0x29, 0x55, 0x8a, 0x45, + 0x89, 0x92, 0x86, 0xa6, 0x82, 0x4b, 0x11, 0x9d, 0x7e, 0xe3, 0x42, 0xa8, 0x0b, 0x3b, 0x41, 0x1c, + 0xa8, 0x80, 0x86, 0x64, 0x40, 0xbd, 0x0b, 0x3e, 0x1c, 0x3a, 0x1b, 0xfd, 0x87, 0x17, 0xaa, 0x0e, + 0xd1, 0xb5, 0x00, 0xf4, 0x18, 0x34, 0xe5, 0x0c, 0xbf, 0xd6, 0x4b, 0x10, 0xd1, 0x69, 0x8a, 0x7d, + 0x00, 0xc8, 0xe1, 0x48, 0x34, 0x09, 0x55, 0x90, 0x84, 0x01, 0x13, 0xc6, 0x47, 0x79, 0xbc, 0xeb, + 0x56, 0x9e, 0xcd, 0x16, 0x50, 0x0f, 0x0e, 0x4c, 0x13, 0xe8, 0x20, 0x64, 0x44, 0x2a, 0xaa, 0x26, + 0x92, 0xe8, 0x0b, 0xa6, 0x0d, 0x52, 0x68, 0x55, 0x3b, 0xb5, 0x74, 0x57, 0xdd, 0x83, 0x23, 0xee, + 0x33, 0xfc, 0xde, 0x2c, 0xff, 0xdc, 0xa4, 0xeb, 0xa0, 0x6c, 0xfc, 0x99, 0x83, 0x4a, 0xa6, 0x0d, + 0xd7, 0xa9, 0xd5, 0x97, 0x90, 0x76, 0x8a, 0xf8, 0x2c, 0xa4, 0x97, 0xeb, 0x2b, 0x55, 0x76, 0xf9, + 0xc7, 0x3a, 0x1d, 0x3d, 0x81, 0x83, 0x98, 0xc7, 0x64, 0x48, 0x15, 0x0d, 0xb3, 0xe2, 0x0b, 0x6f, + 0x11, 0xbf, 0x17, 0xf3, 0xb8, 0xa7, 0xd3, 0xe7, 0xb4, 0x77, 0x6f, 0xc3, 0x2d, 0xeb, 0x66, 0x2e, + 0x48, 0xd6, 0x82, 0xcd, 0x5d, 0xd8, 0x39, 0x0b, 0xbc, 0x8b, 0x5e, 0x20, 0xa4, 0xb2, 0x66, 0x6b, + 0x22, 0xa8, 0x61, 0x3e, 0x89, 0x7d, 0xcc, 0x07, 0x41, 0xec, 0x62, 0x3f, 0x41, 0xf9, 0x5b, 0x91, + 0x78, 0x4f, 0x07, 0x6e, 0x0c, 0x7d, 0x07, 0x65, 0x6f, 0x1c, 0x84, 0x7e, 0xea, 0x64, 0x3b, 0x8e, + 0x5a, 0x2b, 0x9d, 0xfc, 0x94, 0x53, 0xbf, 0x4b, 0x43, 0x1a, 0x7b, 0x41, 0x3c, 0xb2, 0x78, 0x5c, + 0x32, 0x68, 0x5b, 0xc8, 0xe6, 0x7d, 0x28, 0x1e, 0xf9, 0xd2, 0x31, 0xd7, 0x61, 0xdb, 0x0b, 0x27, + 0x52, 0x31, 0x91, 0x7a, 0xd8, 0x7d, 0x36, 0xff, 0xc9, 0x43, 0xf1, 0xf5, 0x2c, 0xef, 0x13, 0xa8, + 0x0c, 0x0c, 0x29, 0x13, 0xc4, 0x4d, 0xc4, 0x5c, 0xab, 0xd8, 0xcd, 0xd7, 0x73, 0xb8, 0x9c, 0x2e, + 0x98, 0x4b, 0xb1, 0x28, 0x35, 0xff, 0x3f, 0xa4, 0xa2, 0xef, 0x61, 0x67, 0x48, 0xc3, 0x50, 0xdb, + 0x2c, 0xe5, 0x2b, 0xbc, 0x23, 0x5f, 0x35, 0x25, 0x70, 0x94, 0x2d, 0xa8, 0x31, 0x5f, 0x92, 0x14, + 0x69, 0xce, 0xb2, 0x69, 0x4e, 0x5e, 0x65, 0xbe, 0x3c, 0xb7, 0x61, 0x73, 0x92, 0x5f, 0xe0, 0x4e, + 0x28, 0x24, 0x09, 0x39, 0xf5, 0x89, 0x60, 0x09, 0x17, 0x4a, 0x37, 0x52, 0x03, 0xd3, 0x1a, 0xbc, + 0x6d, 0xe6, 0x9d, 0x2b, 0x11, 0xc4, 0x23, 0x3b, 0xf3, 0x1a, 0xa1, 0x90, 0x5a, 0x17, 0x4e, 0x19, + 0xce, 0x0d, 0x81, 0xde, 0xa1, 0xf9, 0x7b, 0x01, 0xf6, 0x56, 0x68, 0x46, 0x3d, 0x80, 0x24, 0xf0, + 0x2e, 0xc8, 0x50, 0xdb, 0xc4, 0xcd, 0xec, 0x8f, 0x56, 0x9e, 0x78, 0xc1, 0x4c, 0xfd, 0x0d, 0x3c, + 0x87, 0x44, 0x27, 0x50, 0x12, 0xda, 0x5a, 0x44, 0x68, 0x6f, 0x99, 0x96, 0x95, 0x3a, 0xf7, 0x57, + 0x12, 0x2d, 0x5a, 0xd0, 0x4c, 0xd3, 0x2b, 0x2c, 0xfa, 0x02, 0xb6, 0x34, 0x2c, 0x1c, 0xb8, 0xe9, + 0x71, 0x6f, 0x25, 0xcb, 0xbc, 0x69, 0xfb, 0x1b, 0xd8, 0x41, 0x50, 0x07, 0x0a, 0x9e, 0x2f, 0xdd, + 0x54, 0xbf, 0xb3, 0x12, 0x39, 0x73, 0x64, 0x7f, 0x03, 0xeb, 0x64, 0x8d, 0x99, 0xfa, 0xd2, 0xdd, + 0xe0, 0xd5, 0x98, 0xd7, 0xf3, 0x98, 0xa9, 0x2f, 0xd1, 0x53, 0xa8, 0x4d, 0x7d, 0x49, 0xd8, 0x34, + 0x61, 0x22, 0x88, 0x58, 0xac, 0x68, 0xe8, 0x7a, 0xb4, 0x9e, 0x60, 0x09, 0xd9, 0xbd, 0x09, 0x5b, + 0xee, 0xd6, 0xfe, 0x75, 0x03, 0x2a, 0xce, 0x19, 0xae, 0x43, 0x31, 0xec, 0x1b, 0x5f, 0x0c, 0xd2, + 0xce, 0x5d, 0xdd, 0xcc, 0x5c, 0xab, 0xda, 0xf9, 0x6c, 0xe5, 0x76, 0x19, 0x8a, 0xac, 0x59, 0xad, + 0x39, 0xcd, 0x75, 0xda, 0x0b, 0x97, 0x17, 0xd0, 0xcf, 0x4b, 0xfb, 0x59, 0xce, 0xfa, 0xe6, 0x3b, + 0x5e, 0x87, 0x2c, 0xfb, 0xcc, 0x6f, 0x15, 0xfb, 0x40, 0xa5, 0xac, 0xf6, 0xd2, 0xde, 0x5b, 0xfb, + 0x52, 0xe2, 0x72, 0x34, 0xff, 0xb7, 0xe4, 0x41, 0xcd, 0x0e, 0x3e, 0x35, 0x16, 0x5c, 0xa9, 0x30, + 0x88, 0x47, 0xce, 0x2e, 0x8f, 0xae, 0x51, 0x10, 0xf3, 0x30, 0xbe, 0x98, 0x21, 0xed, 0xc9, 0xf1, + 0x8e, 0xc8, 0x86, 0x91, 0x0f, 0x7b, 0x63, 0x46, 0x43, 0x35, 0x26, 0xde, 0x98, 0x79, 0x17, 0xa9, + 0x64, 0xdb, 0xe7, 0x4f, 0xaf, 0xb1, 0x4f, 0xdf, 0xa0, 0x8f, 0x34, 0xd8, 0x9d, 0x62, 0x77, 0xbc, + 0x18, 0x6a, 0xbc, 0x82, 0xfd, 0x95, 0x7a, 0xd0, 0x07, 0xa0, 0x5f, 0x47, 0xa2, 0xf8, 0x05, 0x8b, + 0xd3, 0x47, 0xa8, 0x18, 0xd1, 0xe9, 0x0b, 0x13, 0x40, 0x1f, 0x42, 0xc9, 0x2c, 0x11, 0xf3, 0xc0, + 0x18, 0xfb, 0xe6, 0x31, 0x98, 0x10, 0xd6, 0x91, 0xc6, 0x0b, 0xd8, 0x5d, 0x12, 0x80, 0xbe, 0x82, + 0x72, 0x66, 0x20, 0xe5, 0xae, 0x31, 0x58, 0x4a, 0xf2, 0x6a, 0x56, 0x35, 0x3f, 0x5f, 0x18, 0x24, + 0x4e, 0xec, 0x0e, 0x94, 0x5e, 0x9e, 0x9e, 0x9f, 0x3d, 0x39, 0x3a, 0xe9, 0x9d, 0x3c, 0x39, 0xae, + 0x6d, 0xe8, 0x00, 0x7e, 0xfe, 0xf2, 0xf4, 0x98, 0xe0, 0xe7, 0xdd, 0x93, 0xd3, 0x5a, 0xae, 0xfb, + 0x00, 0xf6, 0x03, 0x9e, 0x29, 0x9a, 0xad, 0x59, 0x17, 0x65, 0x8a, 0x76, 0xa6, 0x15, 0x9c, 0xe5, + 0x06, 0x5b, 0x46, 0xca, 0xc3, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x83, 0x5e, 0xd9, 0x3c, 0xbf, + 0x0b, 0x00, 0x00, +} diff --git a/xds/internal/balancer/config.go b/xds/internal/balancer/config.go new file mode 100644 index 000000000000..73297d440f8c --- /dev/null +++ b/xds/internal/balancer/config.go @@ -0,0 +1,129 @@ +/* + * + * 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 balancer + +import ( + "encoding/json" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/serviceconfig" +) + +// XDSConfig represents the loadBalancingConfig section of the service config +// for xDS balancers. +type XDSConfig struct { + serviceconfig.LoadBalancingConfig + // BalancerName represents the load balancer to use. + BalancerName string + // ChildPolicy represents the load balancing config for the child + // policy. + ChildPolicy *loadBalancingConfig + // FallBackPolicy represents the load balancing config for the + // fallback. + FallBackPolicy *loadBalancingConfig + // Name to use in EDS query. If not present, defaults to the server + // name from the target URI. + EdsServiceName string + // LRS server to send load reports to. If not present, load reporting + // will be disabled. If set to the empty string, load reporting will + // be sent to the same server that we obtained CDS data from. + // + // TODO: type is StringVal. + LrsLoadReportingServerName string +} + +// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. +// When unmarshalling, we iterate through the childPolicy/fallbackPolicy lists +// and select the first LB policy which has been registered. +func (l *XDSConfig) UnmarshalJSON(data []byte) error { + var val map[string]json.RawMessage + if err := json.Unmarshal(data, &val); err != nil { + return err + } + for k, v := range val { + switch k { + case "balancerName": + if err := json.Unmarshal(v, &l.BalancerName); err != nil { + return err + } + case "childPolicy": + var lbcfgs []*loadBalancingConfig + if err := json.Unmarshal(v, &lbcfgs); err != nil { + return err + } + for _, lbcfg := range lbcfgs { + if balancer.Get(lbcfg.Name) != nil { + l.ChildPolicy = lbcfg + break + } + } + case "fallbackPolicy": + var lbcfgs []*loadBalancingConfig + if err := json.Unmarshal(v, &lbcfgs); err != nil { + return err + } + for _, lbcfg := range lbcfgs { + if balancer.Get(lbcfg.Name) != nil { + l.FallBackPolicy = lbcfg + break + } + } + case "edsServiceName": + if err := json.Unmarshal(v, &l.EdsServiceName); err != nil { + return err + } + case "lrsLoadReportingServerName": + if err := json.Unmarshal(v, &l.LrsLoadReportingServerName); err != nil { + return err + } + } + } + return nil +} + +// MarshalJSON returns a JSON encoding of l. +func (l *XDSConfig) MarshalJSON() ([]byte, error) { + return nil, nil +} + +// loadBalancingConfig represents a single load balancing config, +// stored in JSON format. +type loadBalancingConfig struct { + Name string + Config json.RawMessage +} + +// MarshalJSON returns a JSON encoding of l. +func (l *loadBalancingConfig) MarshalJSON() ([]byte, error) { + m := make(map[string]json.RawMessage) + m[l.Name] = l.Config + return json.Marshal(m) +} + +// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. +func (l *loadBalancingConfig) UnmarshalJSON(data []byte) error { + var cfg map[string]json.RawMessage + if err := json.Unmarshal(data, &cfg); err != nil { + return err + } + for name, config := range cfg { + l.Name = name + l.Config = config + } + return nil +} diff --git a/xds/internal/balancer/xds.go b/xds/internal/balancer/xds.go index c925a52ae74a..894764d336fb 100644 --- a/xds/internal/balancer/xds.go +++ b/xds/internal/balancer/xds.go @@ -33,7 +33,6 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" - xdsinternal "google.golang.org/grpc/xds/internal" "google.golang.org/grpc/xds/internal/balancer/edsbalancer" "google.golang.org/grpc/xds/internal/balancer/lrs" cdspb "google.golang.org/grpc/xds/internal/proto/envoy/api/v2/cds" @@ -90,7 +89,7 @@ func (b *xdsBalancerBuilder) Name() string { } func (b *xdsBalancerBuilder) ParseConfig(c json.RawMessage) (serviceconfig.LoadBalancingConfig, error) { - var cfg xdsinternal.LBConfig + var cfg XDSConfig if err := json.Unmarshal(c, &cfg); err != nil { return nil, fmt.Errorf("unable to unmarshal balancer config %s into xds config", string(c)) } @@ -133,15 +132,15 @@ type xdsBalancer struct { timer *time.Timer noSubConnAlert <-chan struct{} - client *client // may change when passed a different service config - config *xdsinternal.LBConfig // may change when passed a different service config + client *client // may change when passed a different service config + config *XDSConfig // may change when passed a different service config xdsLB edsBalancerInterface fallbackLB balancer.Balancer fallbackInitData *resolver.State // may change when HandleResolved address is called loadStore lrs.Store } -func (x *xdsBalancer) startNewXDSClient(u *xdsinternal.LBConfig) { +func (x *xdsBalancer) startNewXDSClient(u *XDSConfig) { // If the xdsBalancer is in startup stage, then we need to apply the startup timeout for the first // xdsClient to get a response from the traffic director. if x.startup { @@ -240,7 +239,7 @@ func (x *xdsBalancer) handleGRPCUpdate(update interface{}) { } } case *balancer.ClientConnState: - cfg, _ := u.BalancerConfig.(*xdsinternal.LBConfig) + cfg, _ := u.BalancerConfig.(*XDSConfig) if cfg == nil { // service config parsing failed. should never happen. return @@ -505,16 +504,16 @@ func (x *xdsBalancer) cancelFallbackAndSwitchEDSBalancerIfNecessary() { } } -func (x *xdsBalancer) buildFallBackBalancer(c *xdsinternal.LBConfig) { +func (x *xdsBalancer) buildFallBackBalancer(c *XDSConfig) { if c.FallBackPolicy == nil { - x.buildFallBackBalancer(&xdsinternal.LBConfig{ - FallBackPolicy: &xdsinternal.LoadBalancingConfig{ + x.buildFallBackBalancer(&XDSConfig{ + FallBackPolicy: &loadBalancingConfig{ Name: "round_robin", }, }) return } - // builder will always be non-nil, since when parse JSON into xdsinternal.LBConfig, we check whether the specified + // builder will always be non-nil, since when parse JSON into xdsinternal.XDSConfig, we check whether the specified // balancer is registered or not. builder := balancer.Get(c.FallBackPolicy.Name) diff --git a/xds/internal/balancer/xds_lrs_test.go b/xds/internal/balancer/xds_lrs_test.go index e3f66de50edd..0956e6d1187d 100644 --- a/xds/internal/balancer/xds_lrs_test.go +++ b/xds/internal/balancer/xds_lrs_test.go @@ -31,7 +31,6 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/resolver" "google.golang.org/grpc/status" - xdsinternal "google.golang.org/grpc/xds/internal" loadreportpb "google.golang.org/grpc/xds/internal/proto/envoy/api/v2/endpoint/load_report" lrsgrpc "google.golang.org/grpc/xds/internal/proto/envoy/service/load_stats/v2/lrs" lrspb "google.golang.org/grpc/xds/internal/proto/envoy/service/load_stats/v2/lrs" @@ -105,9 +104,9 @@ func (s) TestXdsLoadReporting(t *testing.T) { Nanos: intervalNano, } - cfg := &xdsinternal.LBConfig{ + cfg := &XDSConfig{ BalancerName: addr, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, // Set this to skip cds. + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerA}, // Set this to skip cds. } lb.UpdateClientConnState(balancer.ClientConnState{BalancerConfig: cfg}) td.sendResp(&response{resp: testEDSRespWithoutEndpoints}) diff --git a/xds/internal/balancer/xds_test.go b/xds/internal/balancer/xds_test.go index 0197866f4e2f..d2ca1acc882a 100644 --- a/xds/internal/balancer/xds_test.go +++ b/xds/internal/balancer/xds_test.go @@ -19,19 +19,24 @@ package balancer import ( + "bytes" "encoding/json" "reflect" "sync" "testing" "time" + "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" + wrapperspb "github.com/golang/protobuf/ptypes/wrappers" + "github.com/google/go-cmp/cmp" "google.golang.org/grpc/balancer" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/internal/grpctest" "google.golang.org/grpc/internal/leakcheck" + scpb "google.golang.org/grpc/internal/proto/grpc_service_config" "google.golang.org/grpc/resolver" - xdsinternal "google.golang.org/grpc/xds/internal" + "google.golang.org/grpc/serviceconfig" "google.golang.org/grpc/xds/internal/balancer/lrs" discoverypb "google.golang.org/grpc/xds/internal/proto/envoy/api/v2/discovery" edspb "google.golang.org/grpc/xds/internal/proto/envoy/api/v2/eds" @@ -62,10 +67,10 @@ const ( var ( testBalancerNameFooBar = "foo.bar" - testLBConfigFooBar = &xdsinternal.LBConfig{ + testLBConfigFooBar = &XDSConfig{ BalancerName: testBalancerNameFooBar, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerB}, - FallBackPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerB}, + FallBackPolicy: &loadBalancingConfig{Name: fakeBalancerA}, } specialAddrForBalancerA = resolver.Address{Addr: "this.is.balancer.A"} @@ -175,8 +180,8 @@ type scStateChange struct { type fakeEDSBalancer struct { cc balancer.ClientConn edsChan chan *edspb.ClusterLoadAssignment - childPolicy chan *xdsinternal.LoadBalancingConfig - fallbackPolicy chan *xdsinternal.LoadBalancingConfig + childPolicy chan *loadBalancingConfig + fallbackPolicy chan *loadBalancingConfig subconnStateChange chan *scStateChange loadStore lrs.Store } @@ -196,7 +201,7 @@ func (f *fakeEDSBalancer) HandleEDSResponse(edsResp *edspb.ClusterLoadAssignment } func (f *fakeEDSBalancer) HandleChildPolicy(name string, config json.RawMessage) { - f.childPolicy <- &xdsinternal.LoadBalancingConfig{ + f.childPolicy <- &loadBalancingConfig{ Name: name, Config: config, } @@ -206,8 +211,8 @@ func newFakeEDSBalancer(cc balancer.ClientConn, loadStore lrs.Store) edsBalancer lb := &fakeEDSBalancer{ cc: cc, edsChan: make(chan *edspb.ClusterLoadAssignment, 10), - childPolicy: make(chan *xdsinternal.LoadBalancingConfig, 10), - fallbackPolicy: make(chan *xdsinternal.LoadBalancingConfig, 10), + childPolicy: make(chan *loadBalancingConfig, 10), + fallbackPolicy: make(chan *loadBalancingConfig, 10), subconnStateChange: make(chan *scStateChange, 10), loadStore: loadStore, } @@ -329,10 +334,10 @@ func (s) TestXdsBalanceHandleBalancerConfigBalancerNameUpdate(t *testing.T) { for i := 0; i < 2; i++ { addr, td, _, cleanup := setupServer(t) cleanups = append(cleanups, cleanup) - workingLBConfig := &xdsinternal.LBConfig{ + workingLBConfig := &XDSConfig{ BalancerName: addr, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, - FallBackPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerA}, + FallBackPolicy: &loadBalancingConfig{Name: fakeBalancerA}, } lb.UpdateClientConnState(balancer.ClientConnState{ ResolverState: resolver.State{Addresses: addrs}, @@ -385,39 +390,39 @@ func (s) TestXdsBalanceHandleBalancerConfigChildPolicyUpdate(t *testing.T) { } }() for _, test := range []struct { - cfg *xdsinternal.LBConfig + cfg *XDSConfig responseToSend *discoverypb.DiscoveryResponse - expectedChildPolicy *xdsinternal.LoadBalancingConfig + expectedChildPolicy *loadBalancingConfig }{ { - cfg: &xdsinternal.LBConfig{ - ChildPolicy: &xdsinternal.LoadBalancingConfig{ + cfg: &XDSConfig{ + ChildPolicy: &loadBalancingConfig{ Name: fakeBalancerA, Config: json.RawMessage("{}"), }, }, responseToSend: testEDSRespWithoutEndpoints, - expectedChildPolicy: &xdsinternal.LoadBalancingConfig{ + expectedChildPolicy: &loadBalancingConfig{ Name: string(fakeBalancerA), Config: json.RawMessage(`{}`), }, }, { - cfg: &xdsinternal.LBConfig{ - ChildPolicy: &xdsinternal.LoadBalancingConfig{ + cfg: &XDSConfig{ + ChildPolicy: &loadBalancingConfig{ Name: fakeBalancerB, Config: json.RawMessage("{}"), }, }, - expectedChildPolicy: &xdsinternal.LoadBalancingConfig{ + expectedChildPolicy: &loadBalancingConfig{ Name: string(fakeBalancerB), Config: json.RawMessage(`{}`), }, }, { - cfg: &xdsinternal.LBConfig{}, + cfg: &XDSConfig{}, responseToSend: testCDSResp, - expectedChildPolicy: &xdsinternal.LoadBalancingConfig{ + expectedChildPolicy: &loadBalancingConfig{ Name: "ROUND_ROBIN", }, }, @@ -470,16 +475,16 @@ func (s) TestXdsBalanceHandleBalancerConfigFallBackUpdate(t *testing.T) { addr, td, _, cleanup := setupServer(t) - cfg := xdsinternal.LBConfig{ + cfg := XDSConfig{ BalancerName: addr, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, - FallBackPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerA}, + FallBackPolicy: &loadBalancingConfig{Name: fakeBalancerA}, } lb.UpdateClientConnState(balancer.ClientConnState{BalancerConfig: &cfg}) addrs := []resolver.Address{{Addr: "1.1.1.1:10001"}, {Addr: "2.2.2.2:10002"}, {Addr: "3.3.3.3:10003"}} cfg2 := cfg - cfg2.FallBackPolicy = &xdsinternal.LoadBalancingConfig{Name: fakeBalancerB} + cfg2.FallBackPolicy = &loadBalancingConfig{Name: fakeBalancerB} lb.UpdateClientConnState(balancer.ClientConnState{ ResolverState: resolver.State{Addresses: addrs}, BalancerConfig: &cfg2, @@ -511,7 +516,7 @@ func (s) TestXdsBalanceHandleBalancerConfigFallBackUpdate(t *testing.T) { } cfg3 := cfg - cfg3.FallBackPolicy = &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA} + cfg3.FallBackPolicy = &loadBalancingConfig{Name: fakeBalancerA} lb.UpdateClientConnState(balancer.ClientConnState{ ResolverState: resolver.State{Addresses: addrs}, BalancerConfig: &cfg3, @@ -545,10 +550,10 @@ func (s) TestXdsBalancerHandlerSubConnStateChange(t *testing.T) { addr, td, _, cleanup := setupServer(t) defer cleanup() - cfg := &xdsinternal.LBConfig{ + cfg := &XDSConfig{ BalancerName: addr, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, - FallBackPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerA}, + FallBackPolicy: &loadBalancingConfig{Name: fakeBalancerA}, } lb.UpdateClientConnState(balancer.ClientConnState{BalancerConfig: cfg}) @@ -623,10 +628,10 @@ func (s) TestXdsBalancerFallBackSignalFromEdsBalancer(t *testing.T) { addr, td, _, cleanup := setupServer(t) defer cleanup() - cfg := &xdsinternal.LBConfig{ + cfg := &XDSConfig{ BalancerName: addr, - ChildPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, - FallBackPolicy: &xdsinternal.LoadBalancingConfig{Name: fakeBalancerA}, + ChildPolicy: &loadBalancingConfig{Name: fakeBalancerA}, + FallBackPolicy: &loadBalancingConfig{Name: fakeBalancerA}, } lb.UpdateClientConnState(balancer.ClientConnState{BalancerConfig: cfg}) @@ -684,43 +689,119 @@ func (s) TestXdsBalancerFallBackSignalFromEdsBalancer(t *testing.T) { } } -func (s) TestXdsBalancerConfigParsingSelectingLBPolicy(t *testing.T) { - js := json.RawMessage(`{ -"balancerName": "fake.foo.bar", -"childPolicy": [{"fake_balancer_C": {}}, {"fake_balancer_A": {}}, {"fake_balancer_B": {}}], -"fallbackPolicy": [{"fake_balancer_C": {}}, {"fake_balancer_B": {}}, {"fake_balancer_A": {}}] -}`) - cfg, err := (&xdsBalancerBuilder{}).ParseConfig(js) - if err != nil { - t.Fatalf("unable to unmarshal balancer config into xds config: %v", err) +func TestXdsBalancerConfigParsing(t *testing.T) { + const ( + testEDSName = "eds.service" + testLRSName = "lrs.server" + ) + b := bytes.NewBuffer(nil) + if err := (&jsonpb.Marshaler{}).Marshal(b, &scpb.XdsConfig{ + ChildPolicy: []*scpb.LoadBalancingConfig{ + {Policy: &scpb.LoadBalancingConfig_Xds{}}, + {Policy: &scpb.LoadBalancingConfig_RoundRobin{ + RoundRobin: &scpb.RoundRobinConfig{}, + }}, + }, + FallbackPolicy: []*scpb.LoadBalancingConfig{ + {Policy: &scpb.LoadBalancingConfig_Xds{}}, + {Policy: &scpb.LoadBalancingConfig_PickFirst{ + PickFirst: &scpb.PickFirstConfig{}, + }}, + }, + EdsServiceName: testEDSName, + LrsLoadReportingServerName: &wrapperspb.StringValue{Value: testLRSName}, + }); err != nil { + t.Fatalf("%v", err) } - xdsCfg := cfg.(*xdsinternal.LBConfig) - wantChildPolicy := &xdsinternal.LoadBalancingConfig{Name: string(fakeBalancerA), Config: json.RawMessage(`{}`)} - if !reflect.DeepEqual(xdsCfg.ChildPolicy, wantChildPolicy) { - t.Fatalf("got child policy %v, want %v", xdsCfg.ChildPolicy, wantChildPolicy) + + tests := []struct { + name string + js json.RawMessage + want serviceconfig.LoadBalancingConfig + wantErr bool + }{ + { + name: "jsonpb-generated", + js: b.Bytes(), + want: &XDSConfig{ + ChildPolicy: &loadBalancingConfig{ + Name: "round_robin", + Config: json.RawMessage("{}"), + }, + FallBackPolicy: &loadBalancingConfig{ + Name: "pick_first", + Config: json.RawMessage("{}"), + }, + EdsServiceName: testEDSName, + LrsLoadReportingServerName: testLRSName, + }, + wantErr: false, + }, + { + // json with random balancers, and the first is not registered. + name: "manually-generated", + js: json.RawMessage(` +{ + "balancerName": "fake.foo.bar", + "childPolicy": [ + {"fake_balancer_C": {}}, + {"fake_balancer_A": {}}, + {"fake_balancer_B": {}} + ], + "fallbackPolicy": [ + {"fake_balancer_C": {}}, + {"fake_balancer_B": {}}, + {"fake_balancer_A": {}} + ], + "edsServiceName": "eds.service", + "lrsLoadReportingServerName": "lrs.server" +}`), + want: &XDSConfig{ + BalancerName: "fake.foo.bar", + ChildPolicy: &loadBalancingConfig{ + Name: "fake_balancer_A", + Config: json.RawMessage("{}"), + }, + FallBackPolicy: &loadBalancingConfig{ + Name: "fake_balancer_B", + Config: json.RawMessage("{}"), + }, + EdsServiceName: testEDSName, + LrsLoadReportingServerName: testLRSName, + }, + wantErr: false, + }, } - wantFallbackPolicy := &xdsinternal.LoadBalancingConfig{Name: string(fakeBalancerB), Config: json.RawMessage(`{}`)} - if !reflect.DeepEqual(xdsCfg.FallBackPolicy, wantFallbackPolicy) { - t.Fatalf("got fallback policy %v, want %v", xdsCfg.FallBackPolicy, wantFallbackPolicy) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := &xdsBalancerBuilder{} + got, err := b.ParseConfig(tt.js) + if (err != nil) != tt.wantErr { + t.Errorf("xdsBalancerBuilder.ParseConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !cmp.Equal(got, tt.want) { + t.Errorf(cmp.Diff(got, tt.want)) + } + }) } } - -func (s) TestXdsLoadbalancingConfigParsing(t *testing.T) { +func TestLoadbalancingConfigParsing(t *testing.T) { tests := []struct { name string s string - want *xdsinternal.LBConfig + want *XDSConfig }{ { name: "empty", s: "{}", - want: &xdsinternal.LBConfig{}, + want: &XDSConfig{}, }, { name: "success1", s: `{"childPolicy":[{"pick_first":{}}]}`, - want: &xdsinternal.LBConfig{ - ChildPolicy: &xdsinternal.LoadBalancingConfig{ + want: &XDSConfig{ + ChildPolicy: &loadBalancingConfig{ Name: "pick_first", Config: json.RawMessage(`{}`), }, @@ -729,8 +810,8 @@ func (s) TestXdsLoadbalancingConfigParsing(t *testing.T) { { name: "success2", s: `{"childPolicy":[{"round_robin":{}},{"pick_first":{}}]}`, - want: &xdsinternal.LBConfig{ - ChildPolicy: &xdsinternal.LoadBalancingConfig{ + want: &XDSConfig{ + ChildPolicy: &loadBalancingConfig{ Name: "round_robin", Config: json.RawMessage(`{}`), }, @@ -739,7 +820,7 @@ func (s) TestXdsLoadbalancingConfigParsing(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - var cfg xdsinternal.LBConfig + var cfg XDSConfig if err := json.Unmarshal([]byte(tt.s), &cfg); err != nil || !reflect.DeepEqual(&cfg, tt.want) { t.Errorf("test name: %s, parseFullServiceConfig() = %+v, err: %v, want %+v, ", tt.name, cfg, err, tt.want) } diff --git a/xds/internal/internal.go b/xds/internal/internal.go index 52b3ebb844fc..7403e3f20505 100644 --- a/xds/internal/internal.go +++ b/xds/internal/internal.go @@ -18,11 +18,8 @@ package internal import ( - "encoding/json" "fmt" - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/serviceconfig" basepb "google.golang.org/grpc/xds/internal/proto/envoy/api/v2/core/base" ) @@ -51,88 +48,3 @@ func (lamk Locality) ToProto() *basepb.Locality { SubZone: lamk.SubZone, } } - -// LBConfig represents the loadBalancingConfig section of the service config -// for xDS balancers. -type LBConfig struct { - serviceconfig.LoadBalancingConfig - // BalancerName represents the load balancer to use. - BalancerName string - // ChildPolicy represents the load balancing config for the child policy. - ChildPolicy *LoadBalancingConfig - // FallBackPolicy represents the load balancing config for the fallback. - FallBackPolicy *LoadBalancingConfig -} - -// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. -// When unmarshalling, we iterate through the childPolicy/fallbackPolicy lists -// and select the first LB policy which has been registered. -func (l *LBConfig) UnmarshalJSON(data []byte) error { - var val map[string]json.RawMessage - if err := json.Unmarshal(data, &val); err != nil { - return err - } - for k, v := range val { - switch k { - case "balancerName": - if err := json.Unmarshal(v, &l.BalancerName); err != nil { - return err - } - case "childPolicy": - var lbcfgs []*LoadBalancingConfig - if err := json.Unmarshal(v, &lbcfgs); err != nil { - return err - } - for _, lbcfg := range lbcfgs { - if balancer.Get(lbcfg.Name) != nil { - l.ChildPolicy = lbcfg - break - } - } - case "fallbackPolicy": - var lbcfgs []*LoadBalancingConfig - if err := json.Unmarshal(v, &lbcfgs); err != nil { - return err - } - for _, lbcfg := range lbcfgs { - if balancer.Get(lbcfg.Name) != nil { - l.FallBackPolicy = lbcfg - break - } - } - } - } - return nil -} - -// MarshalJSON returns a JSON encoding of l. -func (l *LBConfig) MarshalJSON() ([]byte, error) { - return nil, nil -} - -// LoadBalancingConfig represents a single load balancing config, -// stored in JSON format. -type LoadBalancingConfig struct { - Name string - Config json.RawMessage -} - -// MarshalJSON returns a JSON encoding of l. -func (l *LoadBalancingConfig) MarshalJSON() ([]byte, error) { - m := make(map[string]json.RawMessage) - m[l.Name] = l.Config - return json.Marshal(m) -} - -// UnmarshalJSON parses the JSON-encoded byte slice in data and stores it in l. -func (l *LoadBalancingConfig) UnmarshalJSON(data []byte) error { - var cfg map[string]json.RawMessage - if err := json.Unmarshal(data, &cfg); err != nil { - return err - } - for name, config := range cfg { - l.Name = name - l.Config = config - } - return nil -} diff --git a/xds/internal/resolver/xds_resolver_test.go b/xds/internal/resolver/xds_resolver_test.go index 372dad8c4802..569a19a8ec66 100644 --- a/xds/internal/resolver/xds_resolver_test.go +++ b/xds/internal/resolver/xds_resolver_test.go @@ -31,7 +31,7 @@ import ( "google.golang.org/grpc/internal" "google.golang.org/grpc/resolver" "google.golang.org/grpc/serviceconfig" - xdsinternal "google.golang.org/grpc/xds/internal" + xdsbalancer "google.golang.org/grpc/xds/internal/balancer" ) // This is initialized at init time. @@ -118,7 +118,7 @@ func (*fakeBalancer) ResolverError(error) { panic("unimplemented") } -// UpdateClientConnState verifies that the received LBConfig matches the +// UpdateClientConnState verifies that the received edsConfig matches the // provided one, and if not, sends an error on the provided channel. func (f *fakeBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error { gotLBConfig, ok := ccs.BalancerConfig.(*wrappedLBConfig) @@ -127,7 +127,7 @@ func (f *fakeBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error return balancer.ErrBadResolverState } - var gotCfg, wantCfg xdsinternal.LBConfig + var gotCfg, wantCfg xdsbalancer.XDSConfig if err := wantCfg.UnmarshalJSON(f.wantLBConfig.lbCfg); err != nil { f.errCh <- fmt.Errorf("unable to unmarshal balancer config %s into xds config", string(f.wantLBConfig.lbCfg)) return balancer.ErrBadResolverState @@ -136,6 +136,7 @@ func (f *fakeBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error f.errCh <- fmt.Errorf("unable to unmarshal balancer config %s into xds config", string(gotLBConfig.lbCfg)) return balancer.ErrBadResolverState } + if !reflect.DeepEqual(gotCfg, wantCfg) { f.errCh <- fmt.Errorf("in fakeBalancer got lbConfig %v, want %v", gotCfg, wantCfg) return balancer.ErrBadResolverState @@ -171,7 +172,7 @@ func (f *fakeBalancerBuilder) ParseConfig(c json.RawMessage) (serviceconfig.Load } // wrappedLBConfig simply wraps the provided LB config with a -// serviceconfig.LoadBalancingConfig interface. +// serviceconfig.loadBalancingConfig interface. type wrappedLBConfig struct { serviceconfig.LoadBalancingConfig lbCfg json.RawMessage