diff --git a/pkg/allocation/converters/converter.go b/pkg/allocation/converters/converter.go index 69f97e4dea..6a8fb73f03 100644 --- a/pkg/allocation/converters/converter.go +++ b/pkg/allocation/converters/converter.go @@ -23,6 +23,7 @@ import ( "agones.dev/agones/pkg/util/runtime" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/wrapperspb" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -73,8 +74,16 @@ func ConvertAllocationRequestToGSA(in *pb.AllocationRequest) *allocationv1.GameS gsa.Spec.Required = *selector } - if runtime.FeatureEnabled(runtime.FeatureCountsAndLists) && in.Priorities != nil { - gsa.Spec.Priorities = convertAllocationPrioritiesToGSAPriorities(in.GetPriorities()) + if runtime.FeatureEnabled(runtime.FeatureCountsAndLists) { + if in.Priorities != nil { + gsa.Spec.Priorities = convertAllocationPrioritiesToGSAPriorities(in.GetPriorities()) + } + if in.Counters != nil { + gsa.Spec.Counters = convertAllocationCountersToGSACounterActions(in.GetCounters()) + } + if in.Lists != nil { + gsa.Spec.Lists = convertAllocationListsToGSAListActions(in.GetLists()) + } } return gsa @@ -120,8 +129,16 @@ func ConvertGSAToAllocationRequest(in *allocationv1.GameServerAllocation) *pb.Al out.MultiClusterSetting.PolicySelector = convertInternalLabelSelectorToLabelSelector(&in.Spec.MultiClusterSetting.PolicySelector) } - if runtime.FeatureEnabled(runtime.FeatureCountsAndLists) && in.Spec.Priorities != nil { - out.Priorities = convertGSAPrioritiesToAllocationPriorities(in.Spec.Priorities) + if runtime.FeatureEnabled(runtime.FeatureCountsAndLists) { + if in.Spec.Priorities != nil { + out.Priorities = convertGSAPrioritiesToAllocationPriorities(in.Spec.Priorities) + } + if in.Spec.Counters != nil { + out.Counters = convertGSACounterActionsToAllocationCounters(in.Spec.Counters) + } + if in.Spec.Lists != nil { + out.Lists = convertGSAListActionsToAllocationLists(in.Spec.Lists) + } } return out @@ -469,3 +486,98 @@ func convertGSAPrioritiesToAllocationPriorities(in []agonesv1.Priority) []*pb.Pr } return out } + +// convertAllocationCountersToGSACounterActions converts a map of AllocationRequest_Counters to a +// map of GameServerAllocationSpec CounterActions +func convertAllocationCountersToGSACounterActions(in map[string]*pb.CounterAction) map[string]allocationv1.CounterAction { + out := map[string]allocationv1.CounterAction{} + for k, v := range in { + ca := allocationv1.CounterAction{} + + if v.Action != nil { + action := v.Action.GetValue() + ca.Action = &action + } + if v.Amount != nil { + amount := v.Amount.GetValue() + ca.Amount = &amount + } + if v.Capacity != nil { + capacity := v.Capacity.GetValue() + ca.Capacity = &capacity + } + + out[k] = ca + } + return out +} + +// convertGSACounterActionsToAllocationCounters converts a map of GameServerAllocationSpec CounterActions +// to a map of AllocationRequest_Counters +func convertGSACounterActionsToAllocationCounters(in map[string]allocationv1.CounterAction) map[string]*pb.CounterAction { + out := map[string]*pb.CounterAction{} + + for k, v := range in { + ca := pb.CounterAction{} + + if v.Action != nil { + ca.Action = wrapperspb.String(*v.Action) + } + if v.Amount != nil { + ca.Amount = wrapperspb.Int64(*v.Amount) + } + if v.Capacity != nil { + ca.Capacity = wrapperspb.Int64(*v.Capacity) + } + + out[k] = &ca + } + return out +} + +// convertAllocationListsToGSAListActions converts a map of AllocationRequest_Lists to a +// map of GameServerAllocationSpec ListActions +func convertAllocationListsToGSAListActions(in map[string]*pb.ListAction) map[string]allocationv1.ListAction { + out := map[string]allocationv1.ListAction{} + + for k, v := range in { + la := allocationv1.ListAction{} + + if v.AddValues != nil { + addValues := v.GetAddValues() + copyValues := make([]string, len(addValues)) + copy(copyValues, addValues) + la.AddValues = copyValues + } + if v.Capacity != nil { + capacity := v.Capacity.GetValue() + la.Capacity = &capacity + } + + out[k] = la + } + + return out +} + +// convertGSAListActionsToAllocationLists converts a map of GameServerAllocationSpec ListActions +// to a map of AllocationRequest_Lists +func convertGSAListActionsToAllocationLists(in map[string]allocationv1.ListAction) map[string]*pb.ListAction { + out := map[string]*pb.ListAction{} + + for k, v := range in { + la := pb.ListAction{} + + if v.AddValues != nil { + copyValues := make([]string, len(v.AddValues)) + copy(copyValues, v.AddValues) + la.AddValues = copyValues + } + if v.Capacity != nil { + la.Capacity = wrapperspb.Int64(*v.Capacity) + } + + out[k] = &la + } + return out +} diff --git a/pkg/allocation/converters/converter_test.go b/pkg/allocation/converters/converter_test.go index b32db446d3..916e20cf66 100644 --- a/pkg/allocation/converters/converter_test.go +++ b/pkg/allocation/converters/converter_test.go @@ -27,6 +27,7 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/wrapperspb" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -34,6 +35,10 @@ import ( func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { allocated := agonesv1.GameServerStateAllocated ready := agonesv1.GameServerStateReady + increment := agonesv1.GameServerPriorityIncrement + decrement := agonesv1.GameServerPriorityDecrement + one := int64(1) + ten := int64(10) tests := []struct { name string @@ -116,6 +121,23 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { Order: pb.Priority_Ascending, }, }, + Counters: map[string]*pb.CounterAction{ + "o": { + Action: wrapperspb.String("Increment"), + Amount: wrapperspb.Int64(1), + }, + "q": { + Action: wrapperspb.String("Decrement"), + Amount: wrapperspb.Int64(1), + Capacity: wrapperspb.Int64(10), + }, + }, + Lists: map[string]*pb.ListAction{ + "p": { + AddValues: []string{"foo", "bar", "baz"}, + Capacity: wrapperspb.Int64(10), + }, + }, Scheduling: pb.AllocationRequest_Packed, Metadata: &pb.MetaPatch{ Labels: map[string]string{ @@ -181,6 +203,23 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { Order: "Ascending", }, }, + Counters: map[string]allocationv1.CounterAction{ + "o": { + Action: &increment, + Amount: &one, + }, + "q": { + Action: &decrement, + Amount: &one, + Capacity: &ten, + }, + }, + Lists: map[string]allocationv1.ListAction{ + "p": { + AddValues: []string{"foo", "bar", "baz"}, + Capacity: &ten, + }, + }, Selectors: []allocationv1.GameServerSelector{ { LabelSelector: metav1.LabelSelector{ @@ -534,6 +573,11 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { }, }, }, + Lists: map[string]*pb.ListAction{ + "d": { + Capacity: wrapperspb.Int64(one), + }, + }, Scheduling: pb.AllocationRequest_Distributed, Metadata: &pb.MetaPatch{}, }, @@ -568,6 +612,11 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { }, }, }, + Lists: map[string]allocationv1.ListAction{ + "d": { + Capacity: &one, + }, + }, Scheduling: apis.Distributed, }, }, @@ -589,6 +638,11 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) { } func TestConvertGSAToAllocationRequest(t *testing.T) { + increment := agonesv1.GameServerPriorityIncrement + decrement := agonesv1.GameServerPriorityDecrement + two := int64(2) + twenty := int64(20) + tests := []struct { name string features string @@ -669,6 +723,25 @@ func TestConvertGSAToAllocationRequest(t *testing.T) { Order: "Descending", }, }, + Counters: map[string]allocationv1.CounterAction{ + "a": { + Action: &decrement, + Amount: &two, + Capacity: &twenty, + }, + "c": { + Action: &increment, + Amount: &two, + }, + }, + Lists: map[string]allocationv1.ListAction{ + "b": { + AddValues: []string{"hello", "world"}, + }, + "d": { + Capacity: &two, + }, + }, Scheduling: apis.Distributed, }, }, @@ -729,6 +802,25 @@ func TestConvertGSAToAllocationRequest(t *testing.T) { Order: pb.Priority_Descending, }, }, + Counters: map[string]*pb.CounterAction{ + "a": { + Action: wrapperspb.String(decrement), + Amount: wrapperspb.Int64(two), + Capacity: wrapperspb.Int64(twenty), + }, + "c": { + Action: wrapperspb.String(increment), + Amount: wrapperspb.Int64(two), + }, + }, + Lists: map[string]*pb.ListAction{ + "b": { + AddValues: []string{"hello", "world"}, + }, + "d": { + Capacity: wrapperspb.Int64(two), + }, + }, }, }, } diff --git a/pkg/allocation/go/allocation.pb.go b/pkg/allocation/go/allocation.pb.go index 0c05de60ff..23c0732465 100644 --- a/pkg/allocation/go/allocation.pb.go +++ b/pkg/allocation/go/allocation.pb.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC All Rights Reserved. +// Copyright 2023 Google LLC All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ import ( _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" ) const ( @@ -276,6 +277,10 @@ type AllocationRequest struct { // Selector set, and will only use any following priority for tie-breaking during sort. // Impacts which GameServer is checked first. Priorities []*Priority `protobuf:"bytes,9,rep,name=priorities,proto3" json:"priorities,omitempty"` + // (Alpha, CountsAndLists feature flag) Counters and Lists provide a set of actions to perform + // on Counters and Lists during allocation. + Counters map[string]*CounterAction `protobuf:"bytes,10,rep,name=counters,proto3" json:"counters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Lists map[string]*ListAction `protobuf:"bytes,11,rep,name=lists,proto3" json:"lists,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *AllocationRequest) Reset() { @@ -375,6 +380,20 @@ func (x *AllocationRequest) GetPriorities() []*Priority { return nil } +func (x *AllocationRequest) GetCounters() map[string]*CounterAction { + if x != nil { + return x.Counters + } + return nil +} + +func (x *AllocationRequest) GetLists() map[string]*ListAction { + if x != nil { + return x.Lists + } + return nil +} + type AllocationResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -981,6 +1000,131 @@ func (x *Priority) GetOrder() Priority_Order { return Priority_Ascending } +// CounterAction is an optional action that can be performed on a Counter at allocation. +// Action: "Increment" or "Decrement" the Counter's Count (optional). Must also define the Amount. +// Amount: The amount to increment or decrement the Count (optional). Must be a positive integer. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max int64. +type CounterAction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Action *wrapperspb.StringValue `protobuf:"bytes,1,opt,name=action,proto3" json:"action,omitempty"` + Amount *wrapperspb.Int64Value `protobuf:"bytes,2,opt,name=amount,proto3" json:"amount,omitempty"` + Capacity *wrapperspb.Int64Value `protobuf:"bytes,3,opt,name=capacity,proto3" json:"capacity,omitempty"` +} + +func (x *CounterAction) Reset() { + *x = CounterAction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_allocation_allocation_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CounterAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CounterAction) ProtoMessage() {} + +func (x *CounterAction) ProtoReflect() protoreflect.Message { + mi := &file_proto_allocation_allocation_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CounterAction.ProtoReflect.Descriptor instead. +func (*CounterAction) Descriptor() ([]byte, []int) { + return file_proto_allocation_allocation_proto_rawDescGZIP(), []int{10} +} + +func (x *CounterAction) GetAction() *wrapperspb.StringValue { + if x != nil { + return x.Action + } + return nil +} + +func (x *CounterAction) GetAmount() *wrapperspb.Int64Value { + if x != nil { + return x.Amount + } + return nil +} + +func (x *CounterAction) GetCapacity() *wrapperspb.Int64Value { + if x != nil { + return x.Capacity + } + return nil +} + +// ListAction is an optional action that can be performed on a List at allocation. +// AddValues: Append values to a List's Values array (optional). Any duplicate values will be ignored. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max 1000. +type ListAction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AddValues []string `protobuf:"bytes,1,rep,name=addValues,proto3" json:"addValues,omitempty"` + Capacity *wrapperspb.Int64Value `protobuf:"bytes,2,opt,name=capacity,proto3" json:"capacity,omitempty"` +} + +func (x *ListAction) Reset() { + *x = ListAction{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_allocation_allocation_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListAction) ProtoMessage() {} + +func (x *ListAction) ProtoReflect() protoreflect.Message { + mi := &file_proto_allocation_allocation_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListAction.ProtoReflect.Descriptor instead. +func (*ListAction) Descriptor() ([]byte, []int) { + return file_proto_allocation_allocation_proto_rawDescGZIP(), []int{11} +} + +func (x *ListAction) GetAddValues() []string { + if x != nil { + return x.AddValues + } + return nil +} + +func (x *ListAction) GetCapacity() *wrapperspb.Int64Value { + if x != nil { + return x.Capacity + } + return nil +} + // The gameserver port info that is allocated. type AllocationResponse_GameServerStatusPort struct { state protoimpl.MessageState @@ -994,7 +1138,7 @@ type AllocationResponse_GameServerStatusPort struct { func (x *AllocationResponse_GameServerStatusPort) Reset() { *x = AllocationResponse_GameServerStatusPort{} if protoimpl.UnsafeEnabled { - mi := &file_proto_allocation_allocation_proto_msgTypes[10] + mi := &file_proto_allocation_allocation_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1007,7 +1151,7 @@ func (x *AllocationResponse_GameServerStatusPort) String() string { func (*AllocationResponse_GameServerStatusPort) ProtoMessage() {} func (x *AllocationResponse_GameServerStatusPort) ProtoReflect() protoreflect.Message { - mi := &file_proto_allocation_allocation_proto_msgTypes[10] + mi := &file_proto_allocation_allocation_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1050,7 +1194,7 @@ type AllocationResponse_GameServerStatusAddress struct { func (x *AllocationResponse_GameServerStatusAddress) Reset() { *x = AllocationResponse_GameServerStatusAddress{} if protoimpl.UnsafeEnabled { - mi := &file_proto_allocation_allocation_proto_msgTypes[11] + mi := &file_proto_allocation_allocation_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1063,7 +1207,7 @@ func (x *AllocationResponse_GameServerStatusAddress) String() string { func (*AllocationResponse_GameServerStatusAddress) ProtoMessage() {} func (x *AllocationResponse_GameServerStatusAddress) ProtoReflect() protoreflect.Message { - mi := &file_proto_allocation_allocation_proto_msgTypes[11] + mi := &file_proto_allocation_allocation_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1105,7 +1249,7 @@ type AllocationResponse_GameServerMetadata struct { func (x *AllocationResponse_GameServerMetadata) Reset() { *x = AllocationResponse_GameServerMetadata{} if protoimpl.UnsafeEnabled { - mi := &file_proto_allocation_allocation_proto_msgTypes[12] + mi := &file_proto_allocation_allocation_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1118,7 +1262,7 @@ func (x *AllocationResponse_GameServerMetadata) String() string { func (*AllocationResponse_GameServerMetadata) ProtoMessage() {} func (x *AllocationResponse_GameServerMetadata) ProtoReflect() protoreflect.Message { - mi := &file_proto_allocation_allocation_proto_msgTypes[12] + mi := &file_proto_allocation_allocation_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,10 +1299,12 @@ var file_proto_allocation_allocation_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc5, 0x05, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf8, 0x07, 0x0a, 0x11, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, @@ -1200,192 +1346,229 @@ var file_proto_allocation_allocation_proto_rawDesc = []byte{ 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x22, 0x31, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x69, 0x6e, 0x67, - 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x61, 0x63, 0x6b, - 0x65, 0x64, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x64, 0x10, 0x01, 0x22, 0xe4, 0x06, 0x0a, 0x12, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0e, - 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x54, 0x0a, 0x09, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x61, - 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, - 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x1a, 0x3e, 0x0a, 0x14, 0x47, 0x61, 0x6d, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x47, 0x0a, 0x17, 0x47, 0x61, 0x6d, 0x65, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x1a, 0xcc, 0x02, 0x0a, 0x12, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x55, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x64, - 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, - 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, - 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x81, 0x01, 0x0a, - 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x0d, 0x92, 0x41, 0x0a, 0xa2, 0x02, 0x07, 0x62, 0x6f, 0x6f, - 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x41, 0x0a, - 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x52, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x22, 0x8b, 0x02, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x50, 0x61, 0x74, 0x63, 0x68, 0x12, 0x39, - 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x48, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, - 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, - 0x50, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3e, - 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, - 0x01, 0x0a, 0x0d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x12, 0x4c, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x3e, - 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, - 0x05, 0x0a, 0x12, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x67, 0x61, 0x6d, 0x65, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x2e, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, - 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x0f, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, - 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x61, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x05, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, - 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x69, - 0x73, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x52, 0x0a, - 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, - 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x2b, 0x0a, 0x0f, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, 0x10, 0x00, 0x12, - 0x0d, 0x0a, 0x09, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x22, 0x58, - 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, - 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, - 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, - 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x41, - 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, - 0x6d, 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x7c, 0x0a, 0x0c, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x24, 0x0a, 0x0d, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x41, 0x76, 0x61, - 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, 0x61, - 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x08, 0x50, - 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, - 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x4f, 0x72, - 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x1d, 0x0a, 0x04, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x10, 0x00, 0x12, - 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x10, 0x01, 0x22, 0x26, 0x0a, 0x05, 0x4f, 0x72, 0x64, - 0x65, 0x72, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, - 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x10, - 0x01, 0x32, 0x80, 0x01, 0x0a, 0x11, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x1d, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x67, 0x61, 0x6d, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x01, 0x2a, 0x42, 0x6e, 0x5a, 0x0c, 0x2e, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x92, 0x41, 0x5d, 0x12, 0x34, 0x0a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x0f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x2a, 0x01, 0x02, - 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, - 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x6a, 0x73, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x12, 0x47, 0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0a, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x3e, 0x0a, 0x05, 0x6c, + 0x69, 0x73, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x1a, 0x56, 0x0a, 0x0d, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x50, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x31, 0x0a, 0x12, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x69, 0x6e, 0x67, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x50, + 0x61, 0x63, 0x6b, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x64, 0x10, 0x01, 0x22, 0xe4, 0x06, 0x0a, 0x12, 0x41, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x26, 0x0a, 0x0e, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x54, 0x0a, 0x09, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x36, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x52, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x1a, 0x3e, 0x0a, 0x14, 0x47, 0x61, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x47, 0x0a, 0x17, 0x47, 0x61, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x1a, 0xcc, 0x02, 0x0a, 0x12, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x55, 0x0a, 0x06, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x12, 0x64, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, + 0x81, 0x01, 0x0a, 0x13, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x0d, 0x92, 0x41, 0x0a, 0xa2, 0x02, 0x07, + 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x41, 0x0a, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x52, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x22, 0x8b, 0x02, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x50, 0x61, 0x74, 0x63, + 0x68, 0x12, 0x39, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x50, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x48, 0x0a, 0x0b, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x50, 0x61, 0x74, 0x63, 0x68, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x9d, 0x01, 0x0a, 0x0d, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x9d, 0x05, 0x0a, 0x12, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, + 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x58, 0x0a, 0x0f, 0x67, + 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x08, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x05, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x05, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x58, 0x0a, 0x0d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x52, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2b, 0x0a, 0x0f, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44, 0x59, + 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x4c, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, + 0x01, 0x22, 0x58, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, + 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, + 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x0f, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, + 0x61, 0x78, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, + 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, + 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, + 0x7c, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x24, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x69, 0x6e, 0x41, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6d, 0x69, 0x6e, + 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x78, + 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0c, 0x6d, 0x61, 0x78, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x22, 0xc4, 0x01, + 0x0a, 0x08, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x1d, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x10, 0x01, 0x22, 0x26, 0x0a, 0x05, + 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x10, 0x01, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x06, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x37, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x22, 0x63, 0x0a, 0x0a, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x32, + 0x80, 0x01, 0x0a, 0x11, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x65, 0x12, 0x1d, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, + 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1e, 0x2e, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x6c, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x15, 0x2f, 0x67, 0x61, 0x6d, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x01, 0x2a, 0x42, 0x6e, 0x5a, 0x0c, 0x2e, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x92, 0x41, 0x5d, 0x12, 0x34, 0x0a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, + 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x0f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x65, 0x74, 0x2a, 0x01, 0x02, 0x32, 0x10, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, + 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, + 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1401,33 +1584,39 @@ func file_proto_allocation_allocation_proto_rawDescGZIP() []byte { } var file_proto_allocation_allocation_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_proto_allocation_allocation_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_proto_allocation_allocation_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_proto_allocation_allocation_proto_goTypes = []interface{}{ - (AllocationRequest_SchedulingStrategy)(0), // 0: allocation.AllocationRequest.SchedulingStrategy - (GameServerSelector_GameServerState)(0), // 1: allocation.GameServerSelector.GameServerState - (Priority_Type)(0), // 2: allocation.Priority.Type - (Priority_Order)(0), // 3: allocation.Priority.Order - (*AllocationRequest)(nil), // 4: allocation.AllocationRequest - (*AllocationResponse)(nil), // 5: allocation.AllocationResponse - (*MultiClusterSetting)(nil), // 6: allocation.MultiClusterSetting - (*MetaPatch)(nil), // 7: allocation.MetaPatch - (*LabelSelector)(nil), // 8: allocation.LabelSelector - (*GameServerSelector)(nil), // 9: allocation.GameServerSelector - (*PlayerSelector)(nil), // 10: allocation.PlayerSelector - (*CounterSelector)(nil), // 11: allocation.CounterSelector - (*ListSelector)(nil), // 12: allocation.ListSelector - (*Priority)(nil), // 13: allocation.Priority - (*AllocationResponse_GameServerStatusPort)(nil), // 14: allocation.AllocationResponse.GameServerStatusPort - (*AllocationResponse_GameServerStatusAddress)(nil), // 15: allocation.AllocationResponse.GameServerStatusAddress - (*AllocationResponse_GameServerMetadata)(nil), // 16: allocation.AllocationResponse.GameServerMetadata - nil, // 17: allocation.AllocationResponse.GameServerMetadata.LabelsEntry - nil, // 18: allocation.AllocationResponse.GameServerMetadata.AnnotationsEntry - nil, // 19: allocation.MetaPatch.LabelsEntry - nil, // 20: allocation.MetaPatch.AnnotationsEntry - nil, // 21: allocation.LabelSelector.MatchLabelsEntry - nil, // 22: allocation.GameServerSelector.MatchLabelsEntry - nil, // 23: allocation.GameServerSelector.CountersEntry - nil, // 24: allocation.GameServerSelector.ListsEntry + (AllocationRequest_SchedulingStrategy)(0), // 0: allocation.AllocationRequest.SchedulingStrategy + (GameServerSelector_GameServerState)(0), // 1: allocation.GameServerSelector.GameServerState + (Priority_Type)(0), // 2: allocation.Priority.Type + (Priority_Order)(0), // 3: allocation.Priority.Order + (*AllocationRequest)(nil), // 4: allocation.AllocationRequest + (*AllocationResponse)(nil), // 5: allocation.AllocationResponse + (*MultiClusterSetting)(nil), // 6: allocation.MultiClusterSetting + (*MetaPatch)(nil), // 7: allocation.MetaPatch + (*LabelSelector)(nil), // 8: allocation.LabelSelector + (*GameServerSelector)(nil), // 9: allocation.GameServerSelector + (*PlayerSelector)(nil), // 10: allocation.PlayerSelector + (*CounterSelector)(nil), // 11: allocation.CounterSelector + (*ListSelector)(nil), // 12: allocation.ListSelector + (*Priority)(nil), // 13: allocation.Priority + (*CounterAction)(nil), // 14: allocation.CounterAction + (*ListAction)(nil), // 15: allocation.ListAction + nil, // 16: allocation.AllocationRequest.CountersEntry + nil, // 17: allocation.AllocationRequest.ListsEntry + (*AllocationResponse_GameServerStatusPort)(nil), // 18: allocation.AllocationResponse.GameServerStatusPort + (*AllocationResponse_GameServerStatusAddress)(nil), // 19: allocation.AllocationResponse.GameServerStatusAddress + (*AllocationResponse_GameServerMetadata)(nil), // 20: allocation.AllocationResponse.GameServerMetadata + nil, // 21: allocation.AllocationResponse.GameServerMetadata.LabelsEntry + nil, // 22: allocation.AllocationResponse.GameServerMetadata.AnnotationsEntry + nil, // 23: allocation.MetaPatch.LabelsEntry + nil, // 24: allocation.MetaPatch.AnnotationsEntry + nil, // 25: allocation.LabelSelector.MatchLabelsEntry + nil, // 26: allocation.GameServerSelector.MatchLabelsEntry + nil, // 27: allocation.GameServerSelector.CountersEntry + nil, // 28: allocation.GameServerSelector.ListsEntry + (*wrapperspb.StringValue)(nil), // 29: google.protobuf.StringValue + (*wrapperspb.Int64Value)(nil), // 30: google.protobuf.Int64Value } var file_proto_allocation_allocation_proto_depIdxs = []int32{ 6, // 0: allocation.AllocationRequest.multiClusterSetting:type_name -> allocation.MultiClusterSetting @@ -1438,31 +1627,39 @@ var file_proto_allocation_allocation_proto_depIdxs = []int32{ 7, // 5: allocation.AllocationRequest.metadata:type_name -> allocation.MetaPatch 9, // 6: allocation.AllocationRequest.gameServerSelectors:type_name -> allocation.GameServerSelector 13, // 7: allocation.AllocationRequest.priorities:type_name -> allocation.Priority - 14, // 8: allocation.AllocationResponse.ports:type_name -> allocation.AllocationResponse.GameServerStatusPort - 15, // 9: allocation.AllocationResponse.addresses:type_name -> allocation.AllocationResponse.GameServerStatusAddress - 16, // 10: allocation.AllocationResponse.metadata:type_name -> allocation.AllocationResponse.GameServerMetadata - 8, // 11: allocation.MultiClusterSetting.policySelector:type_name -> allocation.LabelSelector - 19, // 12: allocation.MetaPatch.labels:type_name -> allocation.MetaPatch.LabelsEntry - 20, // 13: allocation.MetaPatch.annotations:type_name -> allocation.MetaPatch.AnnotationsEntry - 21, // 14: allocation.LabelSelector.matchLabels:type_name -> allocation.LabelSelector.MatchLabelsEntry - 22, // 15: allocation.GameServerSelector.matchLabels:type_name -> allocation.GameServerSelector.MatchLabelsEntry - 1, // 16: allocation.GameServerSelector.gameServerState:type_name -> allocation.GameServerSelector.GameServerState - 10, // 17: allocation.GameServerSelector.players:type_name -> allocation.PlayerSelector - 23, // 18: allocation.GameServerSelector.counters:type_name -> allocation.GameServerSelector.CountersEntry - 24, // 19: allocation.GameServerSelector.lists:type_name -> allocation.GameServerSelector.ListsEntry - 2, // 20: allocation.Priority.type:type_name -> allocation.Priority.Type - 3, // 21: allocation.Priority.order:type_name -> allocation.Priority.Order - 17, // 22: allocation.AllocationResponse.GameServerMetadata.labels:type_name -> allocation.AllocationResponse.GameServerMetadata.LabelsEntry - 18, // 23: allocation.AllocationResponse.GameServerMetadata.annotations:type_name -> allocation.AllocationResponse.GameServerMetadata.AnnotationsEntry - 11, // 24: allocation.GameServerSelector.CountersEntry.value:type_name -> allocation.CounterSelector - 12, // 25: allocation.GameServerSelector.ListsEntry.value:type_name -> allocation.ListSelector - 4, // 26: allocation.AllocationService.Allocate:input_type -> allocation.AllocationRequest - 5, // 27: allocation.AllocationService.Allocate:output_type -> allocation.AllocationResponse - 27, // [27:28] is the sub-list for method output_type - 26, // [26:27] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 16, // 8: allocation.AllocationRequest.counters:type_name -> allocation.AllocationRequest.CountersEntry + 17, // 9: allocation.AllocationRequest.lists:type_name -> allocation.AllocationRequest.ListsEntry + 18, // 10: allocation.AllocationResponse.ports:type_name -> allocation.AllocationResponse.GameServerStatusPort + 19, // 11: allocation.AllocationResponse.addresses:type_name -> allocation.AllocationResponse.GameServerStatusAddress + 20, // 12: allocation.AllocationResponse.metadata:type_name -> allocation.AllocationResponse.GameServerMetadata + 8, // 13: allocation.MultiClusterSetting.policySelector:type_name -> allocation.LabelSelector + 23, // 14: allocation.MetaPatch.labels:type_name -> allocation.MetaPatch.LabelsEntry + 24, // 15: allocation.MetaPatch.annotations:type_name -> allocation.MetaPatch.AnnotationsEntry + 25, // 16: allocation.LabelSelector.matchLabels:type_name -> allocation.LabelSelector.MatchLabelsEntry + 26, // 17: allocation.GameServerSelector.matchLabels:type_name -> allocation.GameServerSelector.MatchLabelsEntry + 1, // 18: allocation.GameServerSelector.gameServerState:type_name -> allocation.GameServerSelector.GameServerState + 10, // 19: allocation.GameServerSelector.players:type_name -> allocation.PlayerSelector + 27, // 20: allocation.GameServerSelector.counters:type_name -> allocation.GameServerSelector.CountersEntry + 28, // 21: allocation.GameServerSelector.lists:type_name -> allocation.GameServerSelector.ListsEntry + 2, // 22: allocation.Priority.type:type_name -> allocation.Priority.Type + 3, // 23: allocation.Priority.order:type_name -> allocation.Priority.Order + 29, // 24: allocation.CounterAction.action:type_name -> google.protobuf.StringValue + 30, // 25: allocation.CounterAction.amount:type_name -> google.protobuf.Int64Value + 30, // 26: allocation.CounterAction.capacity:type_name -> google.protobuf.Int64Value + 30, // 27: allocation.ListAction.capacity:type_name -> google.protobuf.Int64Value + 14, // 28: allocation.AllocationRequest.CountersEntry.value:type_name -> allocation.CounterAction + 15, // 29: allocation.AllocationRequest.ListsEntry.value:type_name -> allocation.ListAction + 21, // 30: allocation.AllocationResponse.GameServerMetadata.labels:type_name -> allocation.AllocationResponse.GameServerMetadata.LabelsEntry + 22, // 31: allocation.AllocationResponse.GameServerMetadata.annotations:type_name -> allocation.AllocationResponse.GameServerMetadata.AnnotationsEntry + 11, // 32: allocation.GameServerSelector.CountersEntry.value:type_name -> allocation.CounterSelector + 12, // 33: allocation.GameServerSelector.ListsEntry.value:type_name -> allocation.ListSelector + 4, // 34: allocation.AllocationService.Allocate:input_type -> allocation.AllocationRequest + 5, // 35: allocation.AllocationService.Allocate:output_type -> allocation.AllocationResponse + 35, // [35:36] is the sub-list for method output_type + 34, // [34:35] is the sub-list for method input_type + 34, // [34:34] is the sub-list for extension type_name + 34, // [34:34] is the sub-list for extension extendee + 0, // [0:34] is the sub-list for field type_name } func init() { file_proto_allocation_allocation_proto_init() } @@ -1592,7 +1789,7 @@ func file_proto_allocation_allocation_proto_init() { } } file_proto_allocation_allocation_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AllocationResponse_GameServerStatusPort); i { + switch v := v.(*CounterAction); i { case 0: return &v.state case 1: @@ -1604,6 +1801,30 @@ func file_proto_allocation_allocation_proto_init() { } } file_proto_allocation_allocation_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListAction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_allocation_allocation_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AllocationResponse_GameServerStatusPort); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_allocation_allocation_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AllocationResponse_GameServerStatusAddress); i { case 0: return &v.state @@ -1615,7 +1836,7 @@ func file_proto_allocation_allocation_proto_init() { return nil } } - file_proto_allocation_allocation_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_proto_allocation_allocation_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AllocationResponse_GameServerMetadata); i { case 0: return &v.state @@ -1635,7 +1856,7 @@ func file_proto_allocation_allocation_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_allocation_allocation_proto_rawDesc, NumEnums: 4, - NumMessages: 21, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/pkg/allocation/go/allocation.pb.gw.go b/pkg/allocation/go/allocation.pb.gw.go index f9fb8591da..3f7602c5e3 100644 --- a/pkg/allocation/go/allocation.pb.gw.go +++ b/pkg/allocation/go/allocation.pb.gw.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC All Rights Reserved. +// Copyright 2023 Google LLC All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/allocation/go/allocation.swagger.json b/pkg/allocation/go/allocation.swagger.json index 9b3413db3e..19124cca38 100644 --- a/pkg/allocation/go/allocation.swagger.json +++ b/pkg/allocation/go/allocation.swagger.json @@ -163,6 +163,19 @@ "$ref": "#/definitions/allocationPriority" }, "description": "(Alpha, CountsAndLists feature flag) The first Priority on the array of Priorities is the most\nimportant for sorting. The allocator will use the first priority for sorting GameServers in the\nSelector set, and will only use any following priority for tie-breaking during sort.\nImpacts which GameServer is checked first." + }, + "counters": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/allocationCounterAction" + }, + "description": "(Alpha, CountsAndLists feature flag) Counters and Lists provide a set of actions to perform\non Counters and Lists during allocation." + }, + "lists": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/allocationListAction" + } } } }, @@ -202,6 +215,23 @@ } } }, + "allocationCounterAction": { + "type": "object", + "properties": { + "action": { + "type": "string" + }, + "amount": { + "type": "string", + "format": "int64" + }, + "capacity": { + "type": "string", + "format": "int64" + } + }, + "description": "CounterAction is an optional action that can be performed on a Counter at allocation.\nAction: \"Increment\" or \"Decrement\" the Counter's Count (optional). Must also define the Amount.\nAmount: The amount to increment or decrement the Count (optional). Must be a positive integer.\nCapacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max int64." + }, "allocationCounterSelector": { "type": "object", "properties": { @@ -268,6 +298,22 @@ }, "description": "LabelSelector used for finding a GameServer with matching labels." }, + "allocationListAction": { + "type": "object", + "properties": { + "addValues": { + "type": "array", + "items": { + "type": "string" + } + }, + "capacity": { + "type": "string", + "format": "int64" + } + }, + "description": "ListAction is an optional action that can be performed on a List at allocation.\nAddValues: Append values to a List's Values array (optional). Any duplicate values will be ignored.\nCapacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max 1000." + }, "allocationListSelector": { "type": "object", "properties": { diff --git a/pkg/allocation/go/allocation_grpc.pb.go b/pkg/allocation/go/allocation_grpc.pb.go index 353bd5bee1..bd4d9a17e2 100644 --- a/pkg/allocation/go/allocation_grpc.pb.go +++ b/pkg/allocation/go/allocation_grpc.pb.go @@ -1,4 +1,4 @@ -// Copyright 2022 Google LLC All Rights Reserved. +// Copyright 2023 Google LLC All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/pkg/apis/allocation/v1/gameserverallocation.go b/pkg/apis/allocation/v1/gameserverallocation.go index 3982f20c8c..bf7b2e861f 100644 --- a/pkg/apis/allocation/v1/gameserverallocation.go +++ b/pkg/apis/allocation/v1/gameserverallocation.go @@ -448,6 +448,41 @@ func validateLists(lists map[string]ListSelector, fldPath *field.Path) field.Err return allErrs } +// validateCounterActions validates that the Counters field has valid values for CounterActions +func validateCounterActions(counters map[string]CounterAction, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + for key, counterAction := range counters { + keyPath := fldPath.Key(key) + if counterAction.Amount != nil && *counterAction.Amount < 0 { + allErrs = append(allErrs, field.Invalid(keyPath.Child("amount"), counterAction.Amount, apivalidation.IsNegativeErrorMsg)) + } + if counterAction.Capacity != nil && *counterAction.Capacity < 0 { + allErrs = append(allErrs, field.Invalid(keyPath.Child("capacity"), counterAction.Capacity, apivalidation.IsNegativeErrorMsg)) + } + if counterAction.Amount != nil && counterAction.Action == nil { + allErrs = append(allErrs, field.Invalid(keyPath, counterAction.Action, "action must be \"Increment\" or \"Decrement\" if the amount is not nil")) + } + if counterAction.Amount == nil && counterAction.Action != nil { + allErrs = append(allErrs, field.Invalid(keyPath, counterAction.Amount, "amount must not be nil if action is not nil")) + } + } + + return allErrs +} + +// validateListActions validates that the Lists field has valid values for ListActions +func validateListActions(lists map[string]ListAction, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + for key, listAction := range lists { + keyPath := fldPath.Key(key) + if listAction.Capacity != nil && *listAction.Capacity < 0 { + allErrs = append(allErrs, field.Invalid(keyPath.Child("capacity"), listAction.Capacity, apivalidation.IsNegativeErrorMsg)) + } + } + + return allErrs +} + // MultiClusterSetting specifies settings for multi-cluster allocation. type MultiClusterSetting struct { Enabled bool `json:"enabled,omitempty"` @@ -525,8 +560,25 @@ func (gsa *GameServerAllocation) Validate() field.ErrorList { allErrs = append(allErrs, gsa.Spec.Selectors[i].Validate(specPath.Child("selectors").Index(i))...) } - if !runtime.FeatureEnabled(runtime.FeatureCountsAndLists) && (gsa.Spec.Priorities != nil) { - allErrs = append(allErrs, field.Forbidden(specPath.Child("priorities"), "Feature CountsAndLists must be enabled if Priorities is specified")) + if !runtime.FeatureEnabled(runtime.FeatureCountsAndLists) { + if gsa.Spec.Priorities != nil { + allErrs = append(allErrs, field.Forbidden(specPath.Child("priorities"), "Feature CountsAndLists must be enabled if Priorities is specified")) + } + if gsa.Spec.Counters != nil { + allErrs = append(allErrs, field.Forbidden(specPath.Child("counters"), "Feature CountsAndLists must be enabled if Counters is specified")) + } + if gsa.Spec.Lists != nil { + allErrs = append(allErrs, field.Forbidden(specPath.Child("lists"), "Feature CountsAndLists must be enabled if Lists is specified")) + } + } + + if runtime.FeatureEnabled(runtime.FeatureCountsAndLists) { + if gsa.Spec.Counters != nil { + allErrs = append(allErrs, validateCounterActions(gsa.Spec.Counters, specPath.Child("counters"))...) + } + if gsa.Spec.Lists != nil { + allErrs = append(allErrs, validateListActions(gsa.Spec.Lists, specPath.Child("lists"))...) + } } allErrs = append(allErrs, gsa.Spec.MetaPatch.Validate(specPath.Child("metadata"))...) diff --git a/pkg/apis/allocation/v1/gameserverallocation_test.go b/pkg/apis/allocation/v1/gameserverallocation_test.go index 4814aea089..7fc3cc347f 100644 --- a/pkg/apis/allocation/v1/gameserverallocation_test.go +++ b/pkg/apis/allocation/v1/gameserverallocation_test.go @@ -16,6 +16,7 @@ package v1 import ( "fmt" + "sort" "testing" "agones.dev/agones/pkg/apis" @@ -1038,6 +1039,135 @@ func TestGameServerListActions(t *testing.T) { } } +func TestValidateCounterActions(t *testing.T) { + t.Parallel() + + runtime.FeatureTestMutex.Lock() + defer runtime.FeatureTestMutex.Unlock() + assert.NoError(t, runtime.ParseFeatures(fmt.Sprintf("%s=true", runtime.FeatureCountsAndLists))) + + fieldPath := field.NewPath("spec.Counters") + decrement := agonesv1.GameServerPriorityDecrement + increment := agonesv1.GameServerPriorityIncrement + + testScenarios := map[string]struct { + counterActions map[string]CounterAction + wantErr bool + }{ + "Valid CounterActions": { + counterActions: map[string]CounterAction{ + "foo": { + Action: &increment, + Amount: int64Pointer(10), + }, + "bar": { + Capacity: int64Pointer(100), + }, + "baz": { + Action: &decrement, + Amount: int64Pointer(1000), + Capacity: int64Pointer(0), + }, + }, + wantErr: false, + }, + "Negative Amount": { + counterActions: map[string]CounterAction{ + "foo": { + Action: &increment, + Amount: int64Pointer(-1), + }, + }, + wantErr: true, + }, + "Negative Capacity": { + counterActions: map[string]CounterAction{ + "foo": { + Capacity: int64Pointer(-20), + }, + }, + wantErr: true, + }, + "Amount but no Action": { + counterActions: map[string]CounterAction{ + "foo": { + Amount: int64Pointer(10), + }, + }, + wantErr: true, + }, + "Action but no Amount": { + counterActions: map[string]CounterAction{ + "foo": { + Action: &decrement, + }, + }, + wantErr: true, + }, + } + + for test, testScenario := range testScenarios { + t.Run(test, func(t *testing.T) { + allErrs := validateCounterActions(testScenario.counterActions, fieldPath) + if testScenario.wantErr { + assert.NotNil(t, allErrs) + } else { + assert.Nil(t, allErrs) + } + }) + } +} + +func TestValidateListActions(t *testing.T) { + t.Parallel() + + runtime.FeatureTestMutex.Lock() + defer runtime.FeatureTestMutex.Unlock() + assert.NoError(t, runtime.ParseFeatures(fmt.Sprintf("%s=true", runtime.FeatureCountsAndLists))) + + fieldPath := field.NewPath("spec.Lists") + + testScenarios := map[string]struct { + listActions map[string]ListAction + wantErr bool + }{ + "Valid ListActions": { + listActions: map[string]ListAction{ + "foo": { + AddValues: []string{"hello", "world"}, + Capacity: int64Pointer(10), + }, + "bar": { + Capacity: int64Pointer(0), + }, + "baz": { + AddValues: []string{}, + }, + }, + wantErr: false, + }, + "Negative Capacity": { + listActions: map[string]ListAction{ + "foo": { + Capacity: int64Pointer(-20), + }, + }, + wantErr: true, + }, + } + + for test, testScenario := range testScenarios { + t.Run(test, func(t *testing.T) { + allErrs := validateListActions(testScenario.listActions, fieldPath) + if testScenario.wantErr { + assert.NotNil(t, allErrs) + } else { + assert.Nil(t, allErrs) + } + }) + } +} + func TestGameServerAllocationValidate(t *testing.T) { t.Parallel() @@ -1057,7 +1187,9 @@ func TestGameServerAllocationValidate(t *testing.T) { runtime.FeatureTestMutex.Lock() defer runtime.FeatureTestMutex.Unlock() - assert.NoError(t, runtime.ParseFeatures(fmt.Sprintf("%s=true", runtime.FeaturePlayerAllocationFilter))) + assert.NoError(t, runtime.ParseFeatures(fmt.Sprintf("%s=true&%s=false", + runtime.FeaturePlayerAllocationFilter, + runtime.FeatureCountsAndLists))) // invalid player selection gsa = &GameServerAllocation{ @@ -1073,16 +1205,25 @@ func TestGameServerAllocationValidate(t *testing.T) { MetaPatch: MetaPatch{ Labels: map[string]string{"$$$": "foo"}, }, + Priorities: []agonesv1.Priority{}, + Counters: map[string]CounterAction{}, + Lists: map[string]ListAction{}, }, } gsa.ApplyDefaults() allErrs = gsa.Validate() - assert.Len(t, allErrs, 4) + sort.Slice(allErrs, func(i, j int) bool { + return allErrs[i].Field > allErrs[j].Field + }) + assert.Len(t, allErrs, 7) assert.Equal(t, "spec.required.players.minAvailable", allErrs[0].Field) - assert.Equal(t, "spec.preferred[0].players.maxAvailable", allErrs[1].Field) + assert.Equal(t, "spec.priorities", allErrs[1].Field) assert.Equal(t, "spec.preferred[0].players.minAvailable", allErrs[2].Field) - assert.Equal(t, "spec.metadata.labels", allErrs[3].Field) + assert.Equal(t, "spec.preferred[0].players.maxAvailable", allErrs[3].Field) + assert.Equal(t, "spec.metadata.labels", allErrs[4].Field) + assert.Equal(t, "spec.lists", allErrs[5].Field) + assert.Equal(t, "spec.counters", allErrs[6].Field) } func TestGameServerAllocationConverter(t *testing.T) { diff --git a/proto/allocation/allocation.proto b/proto/allocation/allocation.proto index 0866cc61c1..dee50f6599 100644 --- a/proto/allocation/allocation.proto +++ b/proto/allocation/allocation.proto @@ -18,6 +18,7 @@ package allocation; option go_package = "./allocation"; import "google/api/annotations.proto"; +import "google/protobuf/wrappers.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { @@ -83,6 +84,11 @@ message AllocationRequest { // Selector set, and will only use any following priority for tie-breaking during sort. // Impacts which GameServer is checked first. repeated Priority priorities = 9; + + // (Alpha, CountsAndLists feature flag) Counters and Lists provide a set of actions to perform + // on Counters and Lists during allocation. + map counters = 10; + map lists = 11; } message AllocationResponse { @@ -196,3 +202,21 @@ message Priority { } Order order = 3; } + +// CounterAction is an optional action that can be performed on a Counter at allocation. +// Action: "Increment" or "Decrement" the Counter's Count (optional). Must also define the Amount. +// Amount: The amount to increment or decrement the Count (optional). Must be a positive integer. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max int64. +message CounterAction { + google.protobuf.StringValue action = 1; + google.protobuf.Int64Value amount = 2; + google.protobuf.Int64Value capacity = 3; +} + +// ListAction is an optional action that can be performed on a List at allocation. +// AddValues: Append values to a List's Values array (optional). Any duplicate values will be ignored. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max 1000. +message ListAction { + repeated string addValues = 1; + google.protobuf.Int64Value capacity = 2; +} diff --git a/sdks/rust/proto/allocation/allocation.proto b/sdks/rust/proto/allocation/allocation.proto index 0866cc61c1..dee50f6599 100644 --- a/sdks/rust/proto/allocation/allocation.proto +++ b/sdks/rust/proto/allocation/allocation.proto @@ -18,6 +18,7 @@ package allocation; option go_package = "./allocation"; import "google/api/annotations.proto"; +import "google/protobuf/wrappers.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { @@ -83,6 +84,11 @@ message AllocationRequest { // Selector set, and will only use any following priority for tie-breaking during sort. // Impacts which GameServer is checked first. repeated Priority priorities = 9; + + // (Alpha, CountsAndLists feature flag) Counters and Lists provide a set of actions to perform + // on Counters and Lists during allocation. + map counters = 10; + map lists = 11; } message AllocationResponse { @@ -196,3 +202,21 @@ message Priority { } Order order = 3; } + +// CounterAction is an optional action that can be performed on a Counter at allocation. +// Action: "Increment" or "Decrement" the Counter's Count (optional). Must also define the Amount. +// Amount: The amount to increment or decrement the Count (optional). Must be a positive integer. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max int64. +message CounterAction { + google.protobuf.StringValue action = 1; + google.protobuf.Int64Value amount = 2; + google.protobuf.Int64Value capacity = 3; +} + +// ListAction is an optional action that can be performed on a List at allocation. +// AddValues: Append values to a List's Values array (optional). Any duplicate values will be ignored. +// Capacity: Update the maximum capacity of the Counter to this number (optional). Min 0, Max 1000. +message ListAction { + repeated string addValues = 1; + google.protobuf.Int64Value capacity = 2; +}