From e0523664f1b0f59bd0d9bae5be3ba2320b5629f5 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Wed, 22 Jan 2025 09:41:43 +0100 Subject: [PATCH 1/8] feat: warm up the normalization cache using variable variations --- .../gen/proto/wg/cosmo/node/v1/node.pb.go | 328 ++++++---- proto/wg/cosmo/node/v1/node.proto | 9 + router-tests/cache_warmup_test.go | 580 ++++++++++++++---- router-tests/ratelimit_test.go | 30 +- .../cache_warmup/skip_include/operations.json | 85 +++ .../my-client/persistedSkipInclude.json | 4 + router-tests/testenv/testenv.go | 59 +- router/core/cache_warmup.go | 59 +- router/gen/proto/wg/cosmo/node/v1/node.pb.go | 327 ++++++---- router/pkg/config/config.go | 10 +- 10 files changed, 1107 insertions(+), 384 deletions(-) create mode 100644 router-tests/testenv/testdata/cache_warmup/skip_include/operations.json create mode 100644 router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/persistedSkipInclude.json diff --git a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go index 3e021a110f..a7911f24ab 100644 --- a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3116,9 +3116,11 @@ type OperationRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } func (x *OperationRequest) Reset() { @@ -3174,6 +3176,67 @@ func (x *OperationRequest) GetExtensions() *Extension { return nil } +func (x *OperationRequest) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + +func (x *OperationRequest) GetVariableVariations() []*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Variables map[string]bool `protobuf:"bytes,1,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} +} + +func (x *VariableVariation) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + type Extension struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3185,7 +3248,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3198,7 +3261,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3211,7 +3274,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -3233,7 +3296,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3246,7 +3309,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3259,7 +3322,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *PersistedQuery) GetSha256Hash() string { @@ -3288,7 +3351,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3301,7 +3364,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3314,7 +3377,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *ClientInfo) GetName() string { @@ -3901,7 +3964,7 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x73, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, + 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0xf1, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, @@ -3910,73 +3973,98 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, - 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, - 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, - 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, - 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, - 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, - 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, - 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, - 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, - 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, - 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, - 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, - 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, - 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, - 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, - 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, - 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, - 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, - 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, - 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, - 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, - 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, - 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcf, - 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, - 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x57, 0x43, 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, - 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, - 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, - 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x13, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, + 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 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, + 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa3, 0x01, 0x0a, + 0x11, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 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, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, 0x4b, 0x0a, 0x0e, 0x50, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, + 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, + 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, + 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x5f, 0x56, + 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, + 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x41, 0x52, 0x52, + 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, 0x0e, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x42, + 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, + 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, + 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, + 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x10, + 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, 0x10, 0x02, 0x2a, 0x86, 0x01, + 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x1d, 0x53, + 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1e, + 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x26, + 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, + 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, + 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x02, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, + 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0c, 0x53, 0x65, 0x6c, 0x66, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcf, 0x01, 0x0a, 0x14, 0x63, 0x6f, + 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, + 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x4e, + 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, + 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, + 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -3992,7 +4080,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 51) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 54) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -4045,31 +4133,34 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*CacheWarmerOperations)(nil), // 48: wg.cosmo.node.v1.CacheWarmerOperations (*Operation)(nil), // 49: wg.cosmo.node.v1.Operation (*OperationRequest)(nil), // 50: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 51: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 52: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 53: wg.cosmo.node.v1.ClientInfo - nil, // 54: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 55: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 56: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 57: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 58: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 59: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*VariableVariation)(nil), // 51: wg.cosmo.node.v1.VariableVariation + (*Extension)(nil), // 52: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 53: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 54: wg.cosmo.node.v1.ClientInfo + nil, // 55: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 56: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 57: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + nil, // 58: wg.cosmo.node.v1.OperationRequest.VariablesEntry + nil, // 59: wg.cosmo.node.v1.VariableVariation.VariablesEntry + (common.EnumStatusCode)(0), // 60: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 61: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 62: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 54, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 55, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 16, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 16, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 7, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 57, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 60, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 13, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 10, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 12, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 17, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration 21, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration 22, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 55, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 56, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind 23, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField 23, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField @@ -4091,7 +4182,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 25, // 32: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition 37, // 33: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable 5, // 34: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 56, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 57, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry 37, // 36: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable 39, // 37: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration 41, // 38: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration @@ -4115,26 +4206,29 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 37, // 56: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 57: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 58: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 59, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 61, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 62, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol 47, // 61: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 46, // 62: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition 47, // 63: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 47, // 64: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 49, // 65: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation 50, // 66: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 53, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 51, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 52, // 69: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 8, // 70: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 40, // 71: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 14, // 72: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 15, // 73: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 73, // [73:74] is the sub-list for method output_type - 72, // [72:73] is the sub-list for method input_type - 72, // [72:72] is the sub-list for extension type_name - 72, // [72:72] is the sub-list for extension extendee - 0, // [0:72] is the sub-list for field type_name + 54, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 52, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 58, // 69: wg.cosmo.node.v1.OperationRequest.variables:type_name -> wg.cosmo.node.v1.OperationRequest.VariablesEntry + 51, // 70: wg.cosmo.node.v1.OperationRequest.variable_variations:type_name -> wg.cosmo.node.v1.VariableVariation + 59, // 71: wg.cosmo.node.v1.VariableVariation.variables:type_name -> wg.cosmo.node.v1.VariableVariation.VariablesEntry + 53, // 72: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 8, // 73: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 40, // 74: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 14, // 75: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 15, // 76: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 76, // [76:77] is the sub-list for method output_type + 75, // [75:76] is the sub-list for method input_type + 75, // [75:75] is the sub-list for extension type_name + 75, // [75:75] is the sub-list for extension extendee + 0, // [0:75] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -4684,7 +4778,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*Extension); i { + switch v := v.(*VariableVariation); i { case 0: return &v.state case 1: @@ -4696,7 +4790,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*PersistedQuery); i { + switch v := v.(*Extension); i { case 0: return &v.state case 1: @@ -4708,6 +4802,18 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*PersistedQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_node_v1_node_proto_msgTypes[48].Exporter = func(v any, i int) any { switch v := v.(*ClientInfo); i { case 0: return &v.state @@ -4734,7 +4840,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_node_v1_node_proto_rawDesc, NumEnums: 6, - NumMessages: 51, + NumMessages: 54, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/wg/cosmo/node/v1/node.proto b/proto/wg/cosmo/node/v1/node.proto index 1f0c721d71..122bbbb2f8 100644 --- a/proto/wg/cosmo/node/v1/node.proto +++ b/proto/wg/cosmo/node/v1/node.proto @@ -329,6 +329,15 @@ message OperationRequest { string operation_name = 1; string query = 2; Extension extensions = 3; + // we're only interested in variables that are relevant for normalization + // as such, we only need booleans that are used for skip/include + // consequently, variables is a map of key->bool + map variables = 4; + repeated VariableVariation variable_variations = 5; +} + +message VariableVariation { + map variables = 1; } message Extension { diff --git a/router-tests/cache_warmup_test.go b/router-tests/cache_warmup_test.go index ce70d79e65..29e1f0acc4 100644 --- a/router-tests/cache_warmup_test.go +++ b/router-tests/cache_warmup_test.go @@ -2,11 +2,14 @@ package integration import ( "net/http" + "os" "testing" "time" "github.com/stretchr/testify/require" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "go.uber.org/zap" + "google.golang.org/protobuf/encoding/protojson" "github.com/wundergraph/cosmo/router-tests/testenv" "github.com/wundergraph/cosmo/router/core" @@ -46,14 +49,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3 + employeeWarmedQueryCount + employeeQueryCount, - QueryNormalizationHits: 4, - ValidationMisses: 3 + employeeWarmedQueryCount, - ValidationHits: 4 + employeeQueryCount, - PlanMisses: 3 + employeeWarmedQueryCount, - PlanHits: 4 + employeeQueryCount, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 3 + employeeWarmedQueryCount + employeeQueryCount, + QueryNormalizationHits: 4, + ValidationMisses: 3 + employeeWarmedQueryCount, + ValidationHits: 4 + employeeQueryCount, + PlanMisses: 3 + employeeWarmedQueryCount, + PlanHits: 4 + employeeQueryCount, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -101,14 +106,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 2, - QueryNormalizationHits: 0, - ValidationMisses: 2, - ValidationHits: 0, - PlanMisses: 1, - PlanHits: 0, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 2, + QueryNormalizationHits: 0, + ValidationMisses: 2, + ValidationHits: 0, + PlanMisses: 1, + PlanHits: 0, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -131,14 +138,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3, - QueryNormalizationHits: 5, - ValidationMisses: 3, - ValidationHits: 5, - PlanMisses: 3, - PlanHits: 5, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 3, + QueryNormalizationHits: 5, + ValidationMisses: 3, + ValidationHits: 5, + PlanMisses: 3, + PlanHits: 5, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -189,14 +198,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - PersistedQueryNormalizationHits: 2, - PersistedQueryNormalizationMisses: 1, - ValidationHits: 2, - ValidationMisses: 1, - PlanHits: 2, - PlanMisses: 1, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationHits: 2, + PersistedQueryNormalizationMisses: 1, + ValidationHits: 2, + ValidationMisses: 1, + PlanHits: 2, + PlanMisses: 1, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -231,14 +242,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - PersistedQueryNormalizationHits: 0, // 1x warmup miss, 1x request miss because of client mismatch, , 1x request miss because checking with operation name - PersistedQueryNormalizationMisses: 3, // same as above - ValidationMisses: 1, // 1x warmup miss, no second miss because client mismatch stops request chain - ValidationHits: 0, // no hits because of client mismatch - PlanMisses: 1, // 1x warmup miss - PlanHits: 0, // no hits because client mismatch stops request chain + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationHits: 0, // 1x warmup miss, 1x request miss because of client mismatch, , 1x request miss because checking with operation name + PersistedQueryNormalizationMisses: 3, // same as above + ValidationMisses: 1, // 1x warmup miss, no second miss because client mismatch stops request chain + ValidationHits: 0, // no hits because of client mismatch + PlanMisses: 1, // 1x warmup miss + PlanHits: 0, // no hits because client mismatch stops request chain + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -266,14 +279,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - PersistedQueryNormalizationHits: 1, // 1x hit after warmup, when called with operation name. No hit from second request because of missing operation name, it recomputes it - PersistedQueryNormalizationMisses: 3, // 1x miss during warmup, 1 miss for first operation trying without operation name, 1 miss for second operation trying without operation name - ValidationHits: 2, - ValidationMisses: 1, - PlanHits: 2, - PlanMisses: 1, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationHits: 1, // 1x hit after warmup, when called with operation name. No hit from second request because of missing operation name, it recomputes it + PersistedQueryNormalizationMisses: 3, // 1x miss during warmup, 1 miss for first operation trying without operation name, 1 miss for second operation trying without operation name + ValidationHits: 2, + ValidationMisses: 1, + PlanHits: 2, + PlanMisses: 1, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -315,14 +330,16 @@ func TestCacheWarmup(t *testing.T) { Timeout: time.Second * 5, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 10, - QueryNormalizationHits: 1, - ValidationMisses: 10, - ValidationHits: 1, - PlanMisses: 10, - PlanHits: 1, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 10, + QueryNormalizationHits: 1, + ValidationMisses: 10, + ValidationHits: 1, + PlanMisses: 10, + PlanHits: 1, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -355,16 +372,18 @@ func TestCacheWarmup(t *testing.T) { ItemsPerSecond: 100, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3 + employeeWarmedQueryCount, - QueryNormalizationHits: 2, - ValidationMisses: 3 + employeeWarmedQueryCount, - ValidationHits: 2, - QueryHashMisses: 3 + employeeWarmedQueryCount, - QueryHashHits: 2, - PlanMisses: 3 + employeeWarmedQueryCount, - PlanHits: 2, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 3 + employeeWarmedQueryCount, + QueryNormalizationHits: 2, + ValidationMisses: 3 + employeeWarmedQueryCount, + ValidationHits: 2, + QueryHashMisses: 3 + employeeWarmedQueryCount, + QueryHashHits: 2, + PlanMisses: 3 + employeeWarmedQueryCount, + PlanHits: 2, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -378,6 +397,333 @@ func TestCacheWarmup(t *testing.T) { require.Equal(t, employeesIDData, res.Body) }) }) + + t.Run("operation with include directive", func(t *testing.T) { + t.Parallel() + + data, err := os.ReadFile("testenv/testdata/cache_warmup/skip_include/operations.json") + require.NoError(t, err) + var warmupOperations nodev1.CacheWarmerOperations + unmarshalOpts := protojson.UnmarshalOptions{DiscardUnknown: true} + err = unmarshalOpts.Unmarshal(data, &warmupOperations) + require.NoError(t, err) + + warmupMisses := int64(0) + for _, operation := range warmupOperations.Operations { + if operation.Request.VariableVariations == nil { + warmupMisses++ + } else { + warmupMisses += int64(len(operation.Request.VariableVariations)) + } + } + + testenv.Run(t, &testenv.Config{ + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + routerConfig.FeatureFlagConfigs = nil + }, + RouterOptions: []core.Option{ + core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ + Enabled: true, + Source: config.CacheWarmupSource{ + Filesystem: &config.CacheWarmupFileSystemSource{ + Path: "testenv/testdata/cache_warmup/skip_include", + }, + }, + }), + }, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationMisses: 2, + QueryNormalizationMisses: warmupMisses - 2, // subtract 2 as these are covered by the persisted query normalization + QueryNormalizationHits: 2, + ValidationMisses: warmupMisses, + ValidationHits: 2, + PlanMisses: warmupMisses, + PlanHits: 2, + }, + }, + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!) {employees { id details @include(if: $include) { forename } } }`, + Variables: []byte(`{"include": true}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"forename":"Jens"}},{"id":2,"details":{"forename":"Dustin"}},{"id":3,"details":{"forename":"Stefan"}},{"id":4,"details":{"forename":"Björn"}},{"id":5,"details":{"forename":"Sergiy"}},{"id":7,"details":{"forename":"Suvij"}},{"id":8,"details":{"forename":"Nithin"}},{"id":10,"details":{"forename":"Eelco"}},{"id":11,"details":{"forename":"Alexandra"}},{"id":12,"details":{"forename":"David"}}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!) {employees { id details @include(if: $include) { forename } } }`, + Variables: []byte(`{"include": false}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":7},{"id":8},{"id":10},{"id":11},{"id":12}]}}`, res.Body) + }) + }) + + t.Run("operation with skip directive", func(t *testing.T) { + t.Parallel() + + data, err := os.ReadFile("testenv/testdata/cache_warmup/skip_include/operations.json") + require.NoError(t, err) + var warmupOperations nodev1.CacheWarmerOperations + unmarshalOpts := protojson.UnmarshalOptions{DiscardUnknown: true} + err = unmarshalOpts.Unmarshal(data, &warmupOperations) + require.NoError(t, err) + + warmupMisses := int64(0) + for _, operation := range warmupOperations.Operations { + if operation.Request.VariableVariations == nil { + warmupMisses++ + } else { + warmupMisses += int64(len(operation.Request.VariableVariations)) + } + } + + testenv.Run(t, &testenv.Config{ + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + routerConfig.FeatureFlagConfigs = nil + }, + RouterOptions: []core.Option{ + core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ + Enabled: true, + Source: config.CacheWarmupSource{ + Filesystem: &config.CacheWarmupFileSystemSource{ + Path: "testenv/testdata/cache_warmup/skip_include", + }, + }, + }), + }, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationMisses: 2, + QueryNormalizationMisses: warmupMisses - 2, // subtract 2 as these are covered by the persisted query normalization + QueryNormalizationHits: 2, + ValidationMisses: warmupMisses, + ValidationHits: 2, + PlanMisses: warmupMisses, + PlanHits: 2, + }, + }, + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query SkipQuery($skip: Boolean!) {employees { id isAvailable details @skip(if: $skip) { forename surname } } }`, + Variables: []byte(`{"skip": true}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"isAvailable":false},{"id":2,"isAvailable":false},{"id":3,"isAvailable":false},{"id":4,"isAvailable":false},{"id":5,"isAvailable":false},{"id":7,"isAvailable":false},{"id":8,"isAvailable":false},{"id":10,"isAvailable":false},{"id":11,"isAvailable":false},{"id":12,"isAvailable":false}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query SkipQuery($skip: Boolean!) {employees { id isAvailable details @skip(if: $skip) { forename surname } } }`, + Variables: []byte(`{"skip": false}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"isAvailable":false,"details":{"forename":"Jens","surname":"Neuse"}},{"id":2,"isAvailable":false,"details":{"forename":"Dustin","surname":"Deus"}},{"id":3,"isAvailable":false,"details":{"forename":"Stefan","surname":"Avram"}},{"id":4,"isAvailable":false,"details":{"forename":"Björn","surname":"Schwenzer"}},{"id":5,"isAvailable":false,"details":{"forename":"Sergiy","surname":"Petrunin"}},{"id":7,"isAvailable":false,"details":{"forename":"Suvij","surname":"Surya"}},{"id":8,"isAvailable":false,"details":{"forename":"Nithin","surname":"Kumar"}},{"id":10,"isAvailable":false,"details":{"forename":"Eelco","surname":"Wiersma"}},{"id":11,"isAvailable":false,"details":{"forename":"Alexandra","surname":"Neuse"}},{"id":12,"isAvailable":false,"details":{"forename":"David","surname":"Stutt"}}]}}`, res.Body) + }) + }) + + t.Run("operation with skip and include directive", func(t *testing.T) { + t.Parallel() + + data, err := os.ReadFile("testenv/testdata/cache_warmup/skip_include/operations.json") + require.NoError(t, err) + var warmupOperations nodev1.CacheWarmerOperations + unmarshalOpts := protojson.UnmarshalOptions{DiscardUnknown: true} + err = unmarshalOpts.Unmarshal(data, &warmupOperations) + require.NoError(t, err) + + warmupMisses := int64(0) + for _, operation := range warmupOperations.Operations { + if operation.Request.VariableVariations == nil { + warmupMisses++ + } else { + warmupMisses += int64(len(operation.Request.VariableVariations)) + } + } + + testenv.Run(t, &testenv.Config{ + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + routerConfig.FeatureFlagConfigs = nil + }, + RouterOptions: []core.Option{ + core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ + Enabled: true, + Source: config.CacheWarmupSource{ + Filesystem: &config.CacheWarmupFileSystemSource{ + Path: "testenv/testdata/cache_warmup/skip_include", + }, + }, + }), + }, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationMisses: 2, + QueryNormalizationMisses: warmupMisses - 2 + 1, // 1x miss for the missing combination in the cache (3rd request) + // subtract 2 as these are covered by the persisted query normalization + QueryNormalizationHits: 2, + ValidationMisses: warmupMisses + 1, // 1x miss for the missing combination in the cache (3rd request) + ValidationHits: 2, + PlanMisses: warmupMisses + 1, // 1x miss for the missing combination in the cache (3rd request) + PlanHits: 2, + }, + }, + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"skip": true, "include": true}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David"}}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"skip": false, "include": false}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","surname":"Stutt"}}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"skip": false, "include": true}`), // missing combination in the cache + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David","surname":"Stutt"}}]}}`, res.Body) + }) + }) + + t.Run("operation with skip and include directive different order should not matter", func(t *testing.T) { + t.Parallel() + + data, err := os.ReadFile("testenv/testdata/cache_warmup/skip_include/operations.json") + require.NoError(t, err) + var warmupOperations nodev1.CacheWarmerOperations + unmarshalOpts := protojson.UnmarshalOptions{DiscardUnknown: true} + err = unmarshalOpts.Unmarshal(data, &warmupOperations) + require.NoError(t, err) + + warmupMisses := int64(0) + for _, operation := range warmupOperations.Operations { + if operation.Request.VariableVariations == nil { + warmupMisses++ + } else { + warmupMisses += int64(len(operation.Request.VariableVariations)) + } + } + + testenv.Run(t, &testenv.Config{ + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + routerConfig.FeatureFlagConfigs = nil + }, + RouterOptions: []core.Option{ + core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ + Enabled: true, + Source: config.CacheWarmupSource{ + Filesystem: &config.CacheWarmupFileSystemSource{ + Path: "testenv/testdata/cache_warmup/skip_include", + }, + }, + }), + }, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationMisses: 2, + QueryNormalizationMisses: warmupMisses - 2 + 1, // 1x miss for the missing combination in the cache (3rd request) + // subtract 2 as these are covered by the persisted query normalization + QueryNormalizationHits: 2, + ValidationMisses: warmupMisses + 1, // 1x miss for the missing combination in the cache (3rd request) + ValidationHits: 2, + PlanMisses: warmupMisses + 1, // 1x miss for the missing combination in the cache (3rd request) + PlanHits: 2, + }, + }, + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"include": true,"skip": true}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David"}}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"include": false,"skip": false}`), + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","surname":"Stutt"}}]}}`, res.Body) + res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }`, + Variables: []byte(`{"include": true,"skip": false}`), // missing combination in the cache + }) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David","surname":"Stutt"}}]}}`, res.Body) + }) + }) + + t.Run("persisted operation with skip include", func(t *testing.T) { + t.Parallel() + + data, err := os.ReadFile("testenv/testdata/cache_warmup/skip_include/operations.json") + require.NoError(t, err) + var warmupOperations nodev1.CacheWarmerOperations + unmarshalOpts := protojson.UnmarshalOptions{DiscardUnknown: true} + err = unmarshalOpts.Unmarshal(data, &warmupOperations) + require.NoError(t, err) + + warmupMisses := int64(0) + for _, operation := range warmupOperations.Operations { + if operation.Request.VariableVariations == nil { + warmupMisses++ + } else { + warmupMisses += int64(len(operation.Request.VariableVariations)) + } + } + + testenv.Run(t, &testenv.Config{ + ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { + routerConfig.FeatureFlagConfigs = nil + }, + RouterOptions: []core.Option{ + core.WithCacheWarmupConfig(&config.CacheWarmupConfiguration{ + Enabled: true, + Source: config.CacheWarmupSource{ + Filesystem: &config.CacheWarmupFileSystemSource{ + Path: "testenv/testdata/cache_warmup/skip_include", + }, + }, + }), + }, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + Before: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: warmupMisses - 2, // subtract 2 as these are covered by the persisted query normalization + PersistedQueryNormalizationMisses: 2, + ValidationMisses: warmupMisses, + PlanMisses: warmupMisses, + }, + }, + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + PersistedQueryNormalizationMisses: 2, + QueryNormalizationMisses: warmupMisses - 2, // subtract 2 as these are covered by the persisted query normalization + ValidationMisses: warmupMisses, + PlanMisses: warmupMisses, + + PersistedQueryNormalizationHits: 2, + ValidationHits: 2, + PlanHits: 2, + }, + }, + }, + }, func(t *testing.T, xEnv *testenv.Environment) { + header := make(http.Header) + header.Add("graphql-client-name", "my-client") + res, err := xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ + Extensions: []byte(`{"persistedQuery": {"version": 1, "sha256Hash": "persistedSkipInclude"}}`), + Header: header, + Variables: []byte(`{"skip": true, "include": true}`), + }) + require.NoError(t, err) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","f":"Jens"}},{"id":2,"details":{"nationality":"GERMAN","f":"Dustin"}},{"id":3,"details":{"nationality":"AMERICAN","f":"Stefan"}},{"id":4,"details":{"nationality":"GERMAN","f":"Björn"}},{"id":5,"details":{"nationality":"UKRAINIAN","f":"Sergiy"}},{"id":7,"details":{"nationality":"INDIAN","f":"Suvij"}},{"id":8,"details":{"nationality":"INDIAN","f":"Nithin"}},{"id":10,"details":{"nationality":"DUTCH","f":"Eelco"}},{"id":11,"details":{"nationality":"GERMAN","f":"Alexandra"}},{"id":12,"details":{"nationality":"ENGLISH","f":"David"}}]}}`, res.Body) + res, err = xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ + Extensions: []byte(`{"persistedQuery": {"version": 1, "sha256Hash": "persistedSkipInclude"}}`), + Header: header, + Variables: []byte(`{"skip": false, "include": false}`), + }) + require.NoError(t, err) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","s":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","s":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","s":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","s":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","s":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","s":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","s":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","s":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","s":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","s":"Stutt"}}]}}`, res.Body) + }) + }) }) t.Run("cache warmup tests for cdn", func(t *testing.T) { @@ -397,14 +743,16 @@ func TestCacheWarmup(t *testing.T) { Enabled: false, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 1, - QueryNormalizationHits: 0, - ValidationMisses: 1, - ValidationHits: 0, - PlanMisses: 1, - PlanHits: 0, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 1, + QueryNormalizationHits: 0, + ValidationMisses: 1, + ValidationHits: 0, + PlanMisses: 1, + PlanHits: 0, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -424,18 +772,20 @@ func TestCacheWarmup(t *testing.T) { Enabled: true, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - // we have additional 2 misses for the employeeQueryCount - because their content differs from what we have in cdn - // this will be possible to solve only by having operation variants populated - QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount + employeeQueryCount, - QueryNormalizationHits: 3, - PersistedQueryNormalizationMisses: cdnPOCount, - PersistedQueryNormalizationHits: 0, - ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 3 + employeeQueryCount, - PlanMisses: cdnOperationCount + cdnPOCount, - PlanHits: 3 + employeeQueryCount, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + // we have additional 2 misses for the employeeQueryCount - because their content differs from what we have in cdn + // this will be possible to solve only by having operation variants populated + QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount + employeeQueryCount, + QueryNormalizationHits: 3, + PersistedQueryNormalizationMisses: cdnPOCount, + PersistedQueryNormalizationHits: 0, + ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, + ValidationHits: 3 + employeeQueryCount, + PlanMisses: cdnOperationCount + cdnPOCount, + PlanHits: 3 + employeeQueryCount, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -483,16 +833,18 @@ func TestCacheWarmup(t *testing.T) { Enabled: true, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, - QueryNormalizationHits: 0, - PersistedQueryNormalizationMisses: cdnPOCount + 2, - PersistedQueryNormalizationHits: 1, - ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 2, - PlanMisses: cdnOperationCount + cdnPOCount, - PlanHits: 2, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, + QueryNormalizationHits: 0, + PersistedQueryNormalizationMisses: cdnPOCount + 2, + PersistedQueryNormalizationHits: 1, + ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, + ValidationHits: 2, + PlanMisses: cdnOperationCount + cdnPOCount, + PlanHits: 2, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { @@ -525,27 +877,29 @@ func TestCacheWarmup(t *testing.T) { Enabled: true, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, - QueryNormalizationHits: 0, - PersistedQueryNormalizationMisses: cdnPOCount, - PersistedQueryNormalizationHits: 0, - ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 0, - PlanMisses: cdnOperationCount + cdnPOCount, - PlanHits: 0, - }, - FeatureFlagAssertions: map[string]testenv.CacheMetricsAssertion{ - "myff": { + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, - QueryNormalizationHits: 1, + QueryNormalizationHits: 0, PersistedQueryNormalizationMisses: cdnPOCount, PersistedQueryNormalizationHits: 0, ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, - ValidationHits: 1, - PlanMisses: cdnOperationCount + featureOperationCount + featureOperationCount, - PlanHits: 1, + ValidationHits: 0, + PlanMisses: cdnOperationCount + cdnPOCount, + PlanHits: 0, + }, + FeatureFlagAssertions: map[string]testenv.CacheMetricsAssertion{ + "myff": { + QueryNormalizationMisses: cdnOperationCount + featureOperationCount + invalidOperationCount, + QueryNormalizationHits: 1, + PersistedQueryNormalizationMisses: cdnPOCount, + PersistedQueryNormalizationHits: 0, + ValidationMisses: cdnOperationCount + cdnPOCount + featureOperationCount + invalidOperationCount, + ValidationHits: 1, + PlanMisses: cdnOperationCount + featureOperationCount + featureOperationCount, + PlanHits: 1, + }, }, }, }, diff --git a/router-tests/ratelimit_test.go b/router-tests/ratelimit_test.go index c83b2d6f0a..db54b7654f 100644 --- a/router-tests/ratelimit_test.go +++ b/router-tests/ratelimit_test.go @@ -51,7 +51,7 @@ func TestRateLimit(t *testing.T) { RouterOptions: []core.Option{ core.WithRateLimitConfig(&config.RateLimitConfiguration{ Enabled: false, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:1", KeyPrefix: "non", }, @@ -85,7 +85,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -120,7 +120,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -161,7 +161,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -224,7 +224,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -277,7 +277,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -320,7 +320,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -375,7 +375,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -409,7 +409,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -444,7 +444,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: true, RejectStatusCode: http.StatusOK, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -482,7 +482,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: true, RejectStatusCode: http.StatusTooManyRequests, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -519,7 +519,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: false, HideStatsFromResponseExtension: true, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -555,7 +555,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: false, HideStatsFromResponseExtension: true, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -601,7 +601,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: true, HideStatsFromResponseExtension: true, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, @@ -648,7 +648,7 @@ func TestRateLimit(t *testing.T) { RejectExceedingRequests: true, HideStatsFromResponseExtension: true, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ Url: "redis://localhost:6379", KeyPrefix: key, }, diff --git a/router-tests/testenv/testdata/cache_warmup/skip_include/operations.json b/router-tests/testenv/testdata/cache_warmup/skip_include/operations.json new file mode 100644 index 0000000000..1f17d57aa4 --- /dev/null +++ b/router-tests/testenv/testdata/cache_warmup/skip_include/operations.json @@ -0,0 +1,85 @@ +{ + "operations": [ + { + "request": { + "query": "query IncludeQuery($include: Boolean!) {employees { id details @include(if: $include) { forename } } }", + "variable_variations": [ + { + "variables": { + "include": true + } + }, + { + "variables": { + "include": false + } + } + ] + } + }, + { + "request": { + "query": "query SkipQuery($skip: Boolean!) {employees { id isAvailable details @skip(if: $skip) { forename surname } } }", + "variable_variations": [ + { + "variables": { + "skip": true + } + }, + { + "variables": { + "skip": false + } + } + ] + } + }, + { + "request": { + "query": "query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality forename @include(if: $include) surname @skip(if: $skip) } } }", + "variable_variations": [ + { + "variables": { + "skip": true, + "include": true + } + }, + { + "variables": { + "skip": false, + "include": false + } + } + ] + } + }, + { + "request": { + "extensions": { + "persistedQuery": { + "version": 1, + "sha256Hash": "persistedSkipInclude" + } + }, + "variable_variations": [ + { + "variables": { + "skip": true, + "include": true + } + }, + { + "variables": { + "skip": false, + "include": false + } + } + ] + }, + "client": { + "name": "my-client", + "version": "missing" + } + } + ] +} \ No newline at end of file diff --git a/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/persistedSkipInclude.json b/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/persistedSkipInclude.json new file mode 100644 index 0000000000..eb0f15b080 --- /dev/null +++ b/router-tests/testenv/testdata/cdn/organization/graph/operations/my-client/persistedSkipInclude.json @@ -0,0 +1,4 @@ +{ + "version": 1, + "body": "query IncludeQuery($include: Boolean!, $skip: Boolean!) { employees { id details { nationality f: forename @include(if: $include) s: surname @skip(if: $skip) } } }" +} \ No newline at end of file diff --git a/router-tests/testenv/testenv.go b/router-tests/testenv/testenv.go index 6dd813f9d6..9d035b21ed 100644 --- a/router-tests/testenv/testenv.go +++ b/router-tests/testenv/testenv.go @@ -10,7 +10,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/hashicorp/consul/sdk/freeport" "io" "log" "math/rand" @@ -30,6 +29,8 @@ import ( "testing" "time" + "github.com/hashicorp/consul/sdk/freeport" + "github.com/wundergraph/cosmo/router/pkg/logging" "go.uber.org/zap/zaptest/observer" @@ -97,12 +98,17 @@ func Run(t *testing.T, cfg *Config, f func(t *testing.T, xEnv *Environment)) { t.Fatalf("could not create environment: %s", err) } t.Cleanup(env.Shutdown) + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.Before != nil { + assertCacheMetrics(t, env, cfg.AssertCacheMetrics.Before.BaseGraphAssertions, "", "before") + for ff, v := range cfg.AssertCacheMetrics.Before.FeatureFlagAssertions { + assertCacheMetrics(t, env, v, ff, "before") + } + } f(t, env) - if cfg.AssertCacheMetrics != nil { - assertCacheMetrics(t, env, cfg.AssertCacheMetrics.BaseGraphAssertions, "") - - for ff, v := range cfg.AssertCacheMetrics.FeatureFlagAssertions { - assertCacheMetrics(t, env, v, ff) + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.After != nil { + assertCacheMetrics(t, env, cfg.AssertCacheMetrics.After.BaseGraphAssertions, "", "after") + for ff, v := range cfg.AssertCacheMetrics.After.FeatureFlagAssertions { + assertCacheMetrics(t, env, v, ff, "after") } } } @@ -116,9 +122,18 @@ func RunWithError(t *testing.T, cfg *Config, f func(t *testing.T, xEnv *Environm return err } t.Cleanup(env.Shutdown) + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.Before != nil { + assertCacheMetrics(t, env, cfg.AssertCacheMetrics.Before.BaseGraphAssertions, "", "before") + for ff, v := range cfg.AssertCacheMetrics.Before.FeatureFlagAssertions { + assertCacheMetrics(t, env, v, ff, "before") + } + } f(t, env) - if cfg.AssertCacheMetrics != nil { - assertCacheMetrics(t, env, cfg.AssertCacheMetrics.BaseGraphAssertions, "") + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.After != nil { + assertCacheMetrics(t, env, cfg.AssertCacheMetrics.After.BaseGraphAssertions, "", "after") + for ff, v := range cfg.AssertCacheMetrics.After.FeatureFlagAssertions { + assertCacheMetrics(t, env, v, ff, "after") + } } return nil @@ -132,25 +147,30 @@ func Bench(b *testing.B, cfg *Config, f func(b *testing.B, xEnv *Environment)) { b.Fatalf("could not create environment: %s", err) } b.Cleanup(env.Shutdown) + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.Before != nil { + assertCacheMetrics(b, env, cfg.AssertCacheMetrics.Before.BaseGraphAssertions, "", "before") + for ff, v := range cfg.AssertCacheMetrics.Before.FeatureFlagAssertions { + assertCacheMetrics(b, env, v, ff, "before") + } + } b.StartTimer() f(b, env) - if cfg.AssertCacheMetrics != nil { - assertCacheMetrics(b, env, cfg.AssertCacheMetrics.BaseGraphAssertions, "") - - for ff, v := range cfg.AssertCacheMetrics.FeatureFlagAssertions { - assertCacheMetrics(b, env, v, ff) + if cfg.AssertCacheMetrics != nil && cfg.AssertCacheMetrics.After != nil { + assertCacheMetrics(b, env, cfg.AssertCacheMetrics.After.BaseGraphAssertions, "", "after") + for ff, v := range cfg.AssertCacheMetrics.After.FeatureFlagAssertions { + assertCacheMetrics(b, env, v, ff, "after") } } } -func assertCacheMetrics(t testing.TB, env *Environment, expected CacheMetricsAssertion, featureFlag string) { +func assertCacheMetrics(t testing.TB, env *Environment, expected CacheMetricsAssertion, featureFlag, hint string) { t.Helper() ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*100) defer cancel() rm := metricdata.ResourceMetrics{} err := env.metricReader.Collect(ctx, &rm) - require.NoError(t, err) + require.NoError(t, err, hint) actual := CacheMetricsAssertion{} for _, sm := range rm.ScopeMetrics { if sm.Scope.Name != "cosmo.router.cache" { @@ -204,7 +224,7 @@ func assertCacheMetrics(t testing.TB, env *Environment, expected CacheMetricsAss } } } - require.Equal(t, expected, actual) + require.Equal(t, expected, actual, hint) } type RouterConfig struct { @@ -274,10 +294,15 @@ type Config struct { EnableKafka bool SubgraphAccessLogsEnabled bool SubgraphAccessLogFields []config.CustomAttribute - AssertCacheMetrics *CacheMetricsAssertions + AssertCacheMetrics *AssertCacheMetrics DisableSimulateCloudExporter bool } +type AssertCacheMetrics struct { + Before *CacheMetricsAssertions + After *CacheMetricsAssertions +} + type CacheMetricsAssertions struct { BaseGraphAssertions CacheMetricsAssertion FeatureFlagAssertions map[string]CacheMetricsAssertion diff --git a/router/core/cache_warmup.go b/router/core/cache_warmup.go index d7621728b2..0d02be8671 100644 --- a/router/core/cache_warmup.go +++ b/router/core/cache_warmup.go @@ -2,6 +2,7 @@ package core import ( "context" + "encoding/json" "errors" "time" @@ -152,13 +153,22 @@ func (w *cacheWarmup) run(ctx context.Context) (int, error) { item := items[idx] err := w.processor.ProcessOperation(ctx, item) if err != nil { - w.log.Error("Failed to process operation, skipping", + fields := []zap.Field{ zap.Error(err), - zap.String("client_name", item.Client.Name), - zap.String("client_version", item.Client.Version), - zap.String("query", item.Request.Query), - zap.String("operation_name", item.Request.OperationName), - ) + } + if item.Client != nil { + fields = append(fields, + zap.String("client_name", item.Client.Name), + zap.String("client_version", item.Client.Version), + ) + } + if item.Request != nil { + fields = append(fields, + zap.String("query", item.Request.Query), + zap.String("operation_name", item.Request.OperationName), + ) + } + w.log.Error("Failed to process operation, skipping", fields...) } select { case <-done: @@ -214,6 +224,24 @@ type CacheWarmupPlanningProcessor struct { } func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, operation *nodev1.Operation) error { + request := operation.GetRequest() + client := operation.GetClient() + variations := request.GetVariableVariations() + if len(variations) == 0 { + return c.processOperation(ctx, request, client) + } + for _, variation := range variations { + variables := variation.GetVariables() + request.Variables = variables + err := c.processOperation(ctx, request, client) + if err != nil { + return err + } + } + return nil +} + +func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, request *nodev1.OperationRequest, client *nodev1.ClientInfo) error { var ( isAPQ bool @@ -225,8 +253,8 @@ func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, ope } var s []byte - if operation.Request.GetExtensions() != nil { - s, err = protojson.Marshal(operation.Request.GetExtensions()) + if request.GetExtensions() != nil { + s, err = protojson.Marshal(request.GetExtensions()) if err != nil { return err } @@ -234,16 +262,23 @@ func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, ope item := &CacheWarmupItem{ Request: GraphQLRequest{ - Query: operation.Request.GetQuery(), - OperationName: operation.Request.GetOperationName(), + Query: request.GetQuery(), + OperationName: request.GetOperationName(), Extensions: s, }, Client: &ClientInfo{ - Name: operation.GetClient().GetName(), - Version: operation.GetClient().GetVersion(), + Name: client.GetName(), + Version: client.GetVersion(), }, } + if request.Variables != nil { + item.Request.Variables, err = json.Marshal(request.Variables) + if err != nil { + return err + } + } + k.parsedOperation.Request = item.Request err = k.unmarshalOperation() diff --git a/router/gen/proto/wg/cosmo/node/v1/node.pb.go b/router/gen/proto/wg/cosmo/node/v1/node.pb.go index d55c99d7ea..8042464f7b 100644 --- a/router/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/router/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3116,9 +3116,11 @@ type OperationRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } func (x *OperationRequest) Reset() { @@ -3174,6 +3176,67 @@ func (x *OperationRequest) GetExtensions() *Extension { return nil } +func (x *OperationRequest) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + +func (x *OperationRequest) GetVariableVariations() []*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Variables map[string]bool `protobuf:"bytes,1,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} +} + +func (x *VariableVariation) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + type Extension struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3185,7 +3248,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3198,7 +3261,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3211,7 +3274,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -3233,7 +3296,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3246,7 +3309,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3259,7 +3322,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *PersistedQuery) GetSha256Hash() string { @@ -3288,7 +3351,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3301,7 +3364,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3314,7 +3377,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *ClientInfo) GetName() string { @@ -3901,7 +3964,7 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x73, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, + 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0xf1, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, @@ -3910,73 +3973,97 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, - 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, - 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, - 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, - 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, - 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, - 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, - 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, - 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, - 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, - 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, - 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, - 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, - 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, - 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, - 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, - 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, - 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, - 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, - 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, - 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, - 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, - 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, - 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, - 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, - 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, - 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, - 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcb, - 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, - 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, - 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, - 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x13, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x12, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3c, + 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 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, + 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa3, 0x01, 0x0a, + 0x11, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 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, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x65, 0x72, 0x73, + 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, 0x4b, 0x0a, 0x0e, 0x50, 0x65, + 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, + 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, + 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, + 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, + 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x5f, 0x56, + 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, + 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x41, 0x52, 0x52, + 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, 0x0e, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x42, + 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, + 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, + 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, + 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, + 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x10, + 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0d, + 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, 0x10, 0x02, 0x2a, 0x86, 0x01, + 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x1d, 0x53, + 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1e, + 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x26, + 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, + 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, + 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x02, + 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, + 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0c, 0x53, 0x65, 0x6c, 0x66, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcb, 0x01, 0x0a, 0x14, 0x63, 0x6f, + 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, + 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x4e, 0xaa, 0x02, 0x10, 0x57, + 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, + 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, + 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3992,7 +4079,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 51) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 54) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -4045,31 +4132,34 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*CacheWarmerOperations)(nil), // 48: wg.cosmo.node.v1.CacheWarmerOperations (*Operation)(nil), // 49: wg.cosmo.node.v1.Operation (*OperationRequest)(nil), // 50: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 51: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 52: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 53: wg.cosmo.node.v1.ClientInfo - nil, // 54: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 55: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 56: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 57: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 58: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 59: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*VariableVariation)(nil), // 51: wg.cosmo.node.v1.VariableVariation + (*Extension)(nil), // 52: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 53: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 54: wg.cosmo.node.v1.ClientInfo + nil, // 55: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 56: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 57: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + nil, // 58: wg.cosmo.node.v1.OperationRequest.VariablesEntry + nil, // 59: wg.cosmo.node.v1.VariableVariation.VariablesEntry + (common.EnumStatusCode)(0), // 60: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 61: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 62: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 54, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 55, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 16, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 16, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 7, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 57, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 60, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 13, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 10, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 12, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 17, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration 21, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration 22, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 55, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 56, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind 23, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField 23, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField @@ -4091,7 +4181,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 25, // 32: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition 37, // 33: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable 5, // 34: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 56, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 57, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry 37, // 36: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable 39, // 37: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration 41, // 38: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration @@ -4115,26 +4205,29 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 37, // 56: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 57: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 58: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 59, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 61, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 62, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol 47, // 61: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 46, // 62: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition 47, // 63: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 47, // 64: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 49, // 65: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation 50, // 66: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 53, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 51, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 52, // 69: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 8, // 70: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 40, // 71: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 14, // 72: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 15, // 73: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 73, // [73:74] is the sub-list for method output_type - 72, // [72:73] is the sub-list for method input_type - 72, // [72:72] is the sub-list for extension type_name - 72, // [72:72] is the sub-list for extension extendee - 0, // [0:72] is the sub-list for field type_name + 54, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 52, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 58, // 69: wg.cosmo.node.v1.OperationRequest.variables:type_name -> wg.cosmo.node.v1.OperationRequest.VariablesEntry + 51, // 70: wg.cosmo.node.v1.OperationRequest.variable_variations:type_name -> wg.cosmo.node.v1.VariableVariation + 59, // 71: wg.cosmo.node.v1.VariableVariation.variables:type_name -> wg.cosmo.node.v1.VariableVariation.VariablesEntry + 53, // 72: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 8, // 73: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 40, // 74: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 14, // 75: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 15, // 76: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 76, // [76:77] is the sub-list for method output_type + 75, // [75:76] is the sub-list for method input_type + 75, // [75:75] is the sub-list for extension type_name + 75, // [75:75] is the sub-list for extension extendee + 0, // [0:75] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -4684,7 +4777,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*Extension); i { + switch v := v.(*VariableVariation); i { case 0: return &v.state case 1: @@ -4696,7 +4789,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*PersistedQuery); i { + switch v := v.(*Extension); i { case 0: return &v.state case 1: @@ -4708,6 +4801,18 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*PersistedQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_node_v1_node_proto_msgTypes[48].Exporter = func(v any, i int) any { switch v := v.(*ClientInfo); i { case 0: return &v.state @@ -4734,7 +4839,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_node_v1_node_proto_rawDesc, NumEnums: 6, - NumMessages: 51, + NumMessages: 54, NumExtensions: 0, NumServices: 1, }, diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index ecf0317f99..aa1efeac94 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -421,10 +421,10 @@ type AuthorizationConfiguration struct { } type RateLimitConfiguration struct { - Enabled bool `yaml:"enabled" envDefault:"false" env:"RATE_LIMIT_ENABLED"` - Strategy string `yaml:"strategy" envDefault:"simple" env:"RATE_LIMIT_STRATEGY"` - SimpleStrategy RateLimitSimpleStrategy `yaml:"simple_strategy"` - Storage RedisConfiguration `yaml:"storage"` + Enabled bool `yaml:"enabled" envDefault:"false" env:"RATE_LIMIT_ENABLED"` + Strategy string `yaml:"strategy" envDefault:"simple" env:"RATE_LIMIT_STRATEGY"` + SimpleStrategy RateLimitSimpleStrategy `yaml:"simple_strategy"` + Storage RateLimitRedisConfiguration `yaml:"storage"` // Debug ensures that retryAfter and resetAfter are set to stable values for testing // Debug also exposes the rate limit key in the response extension for debugging purposes Debug bool `yaml:"debug" envDefault:"false" env:"RATE_LIMIT_DEBUG"` @@ -437,7 +437,7 @@ type RateLimitErrorExtensionCode struct { Code string `yaml:"code" envDefault:"RATE_LIMIT_EXCEEDED" env:"RATE_LIMIT_ERROR_EXTENSION_CODE"` } -type RedisConfiguration struct { +type RateLimitRedisConfiguration struct { Url string `yaml:"url,omitempty" envDefault:"redis://localhost:6379" env:"RATE_LIMIT_REDIS_URL"` KeyPrefix string `yaml:"key_prefix,omitempty" envDefault:"cosmo_rate_limit" env:"RATE_LIMIT_REDIS_KEY_PREFIX"` } From 69faca23055d4a70546b11e226a1015ed6219589 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Wed, 22 Jan 2025 09:43:51 +0100 Subject: [PATCH 2/8] chore: run buf gen --- connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go | 9 ++++++--- router/gen/proto/wg/cosmo/node/v1/node.pb.go | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go index a7911f24ab..38e5f7dc15 100644 --- a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3116,9 +3116,12 @@ type OperationRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + // we're only interested in variables that are relevant for normalization + // as such, we only need booleans that are used for skip/include + // consequently, variables is a map of key->bool Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } diff --git a/router/gen/proto/wg/cosmo/node/v1/node.pb.go b/router/gen/proto/wg/cosmo/node/v1/node.pb.go index 8042464f7b..c85c223304 100644 --- a/router/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/router/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3116,9 +3116,12 @@ type OperationRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` - Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` - Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` + Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` + Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + // we're only interested in variables that are relevant for normalization + // as such, we only need booleans that are used for skip/include + // consequently, variables is a map of key->bool Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } From fdd1e7ba2f02e39dbf908febc833b2d98ccf196b Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Fri, 24 Jan 2025 16:53:22 +0100 Subject: [PATCH 3/8] feat: implement exporting normalization cache warmup data --- .../graphqlmetrics/v1/graphqlmetrics.pb.go | 652 ++++++++++++++++-- .../graphqlmetrics.connect.go | 41 +- .../graphqlmetrics/v1/graphqlmetrics.proto | 40 +- router-tests/graphql_metrics_test.go | 117 +++- router/cmd/instance.go | 16 + router/core/context.go | 7 +- router/core/graph_server.go | 11 +- router/core/graphql_prehandler.go | 4 + router/core/operation_processor.go | 81 ++- router/core/router.go | 166 +++-- router/core/router_metrics.go | 40 +- .../graphqlmetrics/v1/graphqlmetrics.pb.go | 651 +++++++++++++++-- .../graphqlmetrics.connect.go | 41 +- router/internal/graphqlmetrics/exporter.go | 50 +- router/pkg/config/config.go | 16 +- router/pkg/config/config.schema.json | 61 ++ .../pkg/config/testdata/config_defaults.json | 12 +- router/pkg/config/testdata/config_full.json | 12 +- 18 files changed, 1708 insertions(+), 310 deletions(-) diff --git a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index 107671e28f..9d73c3c9c7 100644 --- a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -895,6 +895,358 @@ func (*PublishAggregatedGraphQLRequestMetricsResponse) Descriptor() ([]byte, []i return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{12} } +type NormalizationCacheWarmupData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query *NormalizationCacheWarmupDataQuery `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Encrypted bool `protobuf:"varint,3,opt,name=Encrypted,proto3" json:"Encrypted,omitempty"` + VariableVariations map[uint64]*VariableVariation `protobuf:"bytes,4,rep,name=VariableVariations,proto3" json:"VariableVariations,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *NormalizationCacheWarmupData) Reset() { + *x = NormalizationCacheWarmupData{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupData) ProtoMessage() {} + +func (x *NormalizationCacheWarmupData) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13] + 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 NormalizationCacheWarmupData.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupData) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{13} +} + +func (x *NormalizationCacheWarmupData) GetQuery() *NormalizationCacheWarmupDataQuery { + if x != nil { + return x.Query + } + return nil +} + +func (x *NormalizationCacheWarmupData) GetEncrypted() bool { + if x != nil { + return x.Encrypted + } + return false +} + +func (x *NormalizationCacheWarmupData) GetVariableVariations() map[uint64]*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type NormalizationCacheWarmupDataQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` + Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` +} + +func (x *NormalizationCacheWarmupDataQuery) Reset() { + *x = NormalizationCacheWarmupDataQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupDataQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupDataQuery) ProtoMessage() {} + +func (x *NormalizationCacheWarmupDataQuery) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14] + 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 NormalizationCacheWarmupDataQuery.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupDataQuery) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{14} +} + +func (x *NormalizationCacheWarmupDataQuery) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *NormalizationCacheWarmupDataQuery) GetHash() uint64 { + if x != nil { + return x.Hash + } + return 0 +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VariableValues []*VariableValue `protobuf:"bytes,1,rep,name=VariableValues,proto3" json:"VariableValues,omitempty"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{15} +} + +func (x *VariableVariation) GetVariableValues() []*VariableValue { + if x != nil { + return x.VariableValues + } + return nil +} + +type VariableValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"` + Value bool `protobuf:"varint,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *VariableValue) Reset() { + *x = VariableValue{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableValue) ProtoMessage() {} + +func (x *VariableValue) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16] + 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 VariableValue.ProtoReflect.Descriptor instead. +func (*VariableValue) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{16} +} + +func (x *VariableValue) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *VariableValue) GetValue() bool { + if x != nil { + return x.Value + } + return false +} + +type NormalizationCacheWarmupDataAggregation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Operations map[uint64]*NormalizationCacheWarmupData `protobuf:"bytes,1,rep,name=Operations,proto3" json:"Operations,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *NormalizationCacheWarmupDataAggregation) Reset() { + *x = NormalizationCacheWarmupDataAggregation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupDataAggregation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupDataAggregation) ProtoMessage() {} + +func (x *NormalizationCacheWarmupDataAggregation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17] + 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 NormalizationCacheWarmupDataAggregation.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupDataAggregation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{17} +} + +func (x *NormalizationCacheWarmupDataAggregation) GetOperations() map[uint64]*NormalizationCacheWarmupData { + if x != nil { + return x.Operations + } + return nil +} + +type PublishNormalizationCacheWarmupDataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Aggregation *NormalizationCacheWarmupDataAggregation `protobuf:"bytes,1,opt,name=Aggregation,proto3" json:"Aggregation,omitempty"` +} + +func (x *PublishNormalizationCacheWarmupDataRequest) Reset() { + *x = PublishNormalizationCacheWarmupDataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishNormalizationCacheWarmupDataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishNormalizationCacheWarmupDataRequest) ProtoMessage() {} + +func (x *PublishNormalizationCacheWarmupDataRequest) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18] + 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 PublishNormalizationCacheWarmupDataRequest.ProtoReflect.Descriptor instead. +func (*PublishNormalizationCacheWarmupDataRequest) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{18} +} + +func (x *PublishNormalizationCacheWarmupDataRequest) GetAggregation() *NormalizationCacheWarmupDataAggregation { + if x != nil { + return x.Aggregation + } + return nil +} + +type PublishNormalizationCacheWarmupDataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PublishNormalizationCacheWarmupDataResponse) Reset() { + *x = PublishNormalizationCacheWarmupDataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishNormalizationCacheWarmupDataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishNormalizationCacheWarmupDataResponse) ProtoMessage() {} + +func (x *PublishNormalizationCacheWarmupDataResponse) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19] + 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 PublishNormalizationCacheWarmupDataResponse.ProtoReflect.Descriptor instead. +func (*PublishNormalizationCacheWarmupDataResponse) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{19} +} + var File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto protoreflect.FileDescriptor var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ @@ -1032,53 +1384,135 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, - 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, - 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, - 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xf5, 0x02, 0x0a, 0x15, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, + 0x03, 0x0a, 0x1c, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x53, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, - 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x42, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, - 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xba, 0x01, 0x0a, 0x1f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, - 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, - 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x49, 0x2e, 0x77, 0x67, 0x2e, 0x63, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, + 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x12, 0x80, 0x01, 0x0a, 0x12, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x50, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, + 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x12, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x74, 0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, 0x0a, 0x21, 0x4e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x22, 0x66, 0x0a, 0x11, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x51, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x22, 0x37, 0x0a, 0x0d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x97, 0x02, 0x0a, 0x27, + 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x73, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x53, 0x2e, 0x77, 0x67, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, + 0x70, 0x44, 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x77, 0x0a, 0x0f, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x38, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x2a, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x4a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xa3, 0x02, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x61, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, - 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, - 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, - 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, + 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2d, 0x0a, 0x2b, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, 0x0d, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x51, + 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xb0, 0x04, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x77, 0x67, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0xba, 0x01, 0x0a, 0x1f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x49, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x4a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xb8, + 0x01, 0x0a, 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, + 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x46, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, + 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x47, + 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xa3, 0x02, 0x0a, 0x1e, 0x63, 0x6f, + 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x61, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, 0x57, + 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1094,7 +1528,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP() []byte { } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []any{ (OperationType)(0), // 0: wg.cosmo.graphqlmetrics.v1.OperationType (*RequestInfo)(nil), // 1: wg.cosmo.graphqlmetrics.v1.RequestInfo @@ -1110,7 +1544,16 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []any{ (*PublishOperationCoverageReportResponse)(nil), // 11: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse (*PublishAggregatedGraphQLRequestMetricsRequest)(nil), // 12: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest (*PublishAggregatedGraphQLRequestMetricsResponse)(nil), // 13: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse - nil, // 14: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + (*NormalizationCacheWarmupData)(nil), // 14: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData + (*NormalizationCacheWarmupDataQuery)(nil), // 15: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataQuery + (*VariableVariation)(nil), // 16: wg.cosmo.graphqlmetrics.v1.VariableVariation + (*VariableValue)(nil), // 17: wg.cosmo.graphqlmetrics.v1.VariableValue + (*NormalizationCacheWarmupDataAggregation)(nil), // 18: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation + (*PublishNormalizationCacheWarmupDataRequest)(nil), // 19: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest + (*PublishNormalizationCacheWarmupDataResponse)(nil), // 20: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataResponse + nil, // 21: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + nil, // 22: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry + nil, // 23: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ 7, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo @@ -1118,22 +1561,31 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ 6, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo 4, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo - 14, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + 21, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry 8, // 6: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ArgumentMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo 9, // 7: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.InputMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.InputUsageInfo 2, // 8: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfoAggregation.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo 0, // 9: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType 2, // 10: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo 3, // 11: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest.Aggregation:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfoAggregation - 10, // 12: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - 12, // 13: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest - 11, // 14: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - 13, // 15: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse - 14, // [14:16] is the sub-list for method output_type - 12, // [12:14] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 15, // 12: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.query:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataQuery + 22, // 13: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariations:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry + 17, // 14: wg.cosmo.graphqlmetrics.v1.VariableVariation.VariableValues:type_name -> wg.cosmo.graphqlmetrics.v1.VariableValue + 23, // 15: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.Operations:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry + 18, // 16: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest.Aggregation:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation + 16, // 17: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry.value:type_name -> wg.cosmo.graphqlmetrics.v1.VariableVariation + 14, // 18: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry.value:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData + 10, // 19: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + 12, // 20: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest + 19, // 21: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData:input_type -> wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest + 11, // 22: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + 13, // 23: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse + 20, // 24: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData:output_type -> wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataResponse + 22, // [22:25] is the sub-list for method output_type + 19, // [19:22] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() } @@ -1298,6 +1750,90 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { return nil } } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupDataQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*VariableVariation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*VariableValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupDataAggregation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*PublishNormalizationCacheWarmupDataRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*PublishNormalizationCacheWarmupDataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1305,7 +1841,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc, NumEnums: 1, - NumMessages: 14, + NumMessages: 23, NumExtensions: 0, NumServices: 1, }, diff --git a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go index 8b3405b2d2..0744e4ebef 100644 --- a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go +++ b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go @@ -41,13 +41,17 @@ const ( // GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure is the fully-qualified name of the // GraphQLMetricsService's PublishAggregatedGraphQLMetrics RPC. GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure = "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishAggregatedGraphQLMetrics" + // GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure is the fully-qualified name of + // the GraphQLMetricsService's PublishNormalizationCacheWarmupData RPC. + GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure = "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishNormalizationCacheWarmupData" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - graphQLMetricsServiceServiceDescriptor = v1.File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto.Services().ByName("GraphQLMetricsService") - graphQLMetricsServicePublishGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishGraphQLMetrics") - graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishAggregatedGraphQLMetrics") + graphQLMetricsServiceServiceDescriptor = v1.File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto.Services().ByName("GraphQLMetricsService") + graphQLMetricsServicePublishGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishGraphQLMetrics") + graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishAggregatedGraphQLMetrics") + graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishNormalizationCacheWarmupData") ) // GraphQLMetricsServiceClient is a client for the wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService @@ -56,6 +60,7 @@ type GraphQLMetricsServiceClient interface { // PublishGraphQLMetrics publishes the GraphQL metrics to the metrics service PublishGraphQLMetrics(context.Context, *connect.Request[v1.PublishGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishOperationCoverageReportResponse], error) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) + PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) } // NewGraphQLMetricsServiceClient constructs a client for the @@ -81,13 +86,20 @@ func NewGraphQLMetricsServiceClient(httpClient connect.HTTPClient, baseURL strin connect.WithSchema(graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor), connect.WithClientOptions(opts...), ), + publishNormalizationCacheWarmupData: connect.NewClient[v1.PublishNormalizationCacheWarmupDataRequest, v1.PublishNormalizationCacheWarmupDataResponse]( + httpClient, + baseURL+GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure, + connect.WithSchema(graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // graphQLMetricsServiceClient implements GraphQLMetricsServiceClient. type graphQLMetricsServiceClient struct { - publishGraphQLMetrics *connect.Client[v1.PublishGraphQLRequestMetricsRequest, v1.PublishOperationCoverageReportResponse] - publishAggregatedGraphQLMetrics *connect.Client[v1.PublishAggregatedGraphQLRequestMetricsRequest, v1.PublishAggregatedGraphQLRequestMetricsResponse] + publishGraphQLMetrics *connect.Client[v1.PublishGraphQLRequestMetricsRequest, v1.PublishOperationCoverageReportResponse] + publishAggregatedGraphQLMetrics *connect.Client[v1.PublishAggregatedGraphQLRequestMetricsRequest, v1.PublishAggregatedGraphQLRequestMetricsResponse] + publishNormalizationCacheWarmupData *connect.Client[v1.PublishNormalizationCacheWarmupDataRequest, v1.PublishNormalizationCacheWarmupDataResponse] } // PublishGraphQLMetrics calls @@ -102,12 +114,19 @@ func (c *graphQLMetricsServiceClient) PublishAggregatedGraphQLMetrics(ctx contex return c.publishAggregatedGraphQLMetrics.CallUnary(ctx, req) } +// PublishNormalizationCacheWarmupData calls +// wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData. +func (c *graphQLMetricsServiceClient) PublishNormalizationCacheWarmupData(ctx context.Context, req *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) { + return c.publishNormalizationCacheWarmupData.CallUnary(ctx, req) +} + // GraphQLMetricsServiceHandler is an implementation of the // wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService service. type GraphQLMetricsServiceHandler interface { // PublishGraphQLMetrics publishes the GraphQL metrics to the metrics service PublishGraphQLMetrics(context.Context, *connect.Request[v1.PublishGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishOperationCoverageReportResponse], error) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) + PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) } // NewGraphQLMetricsServiceHandler builds an HTTP handler from the service implementation. It @@ -128,12 +147,20 @@ func NewGraphQLMetricsServiceHandler(svc GraphQLMetricsServiceHandler, opts ...c connect.WithSchema(graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor), connect.WithHandlerOptions(opts...), ) + graphQLMetricsServicePublishNormalizationCacheWarmupDataHandler := connect.NewUnaryHandler( + GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure, + svc.PublishNormalizationCacheWarmupData, + connect.WithSchema(graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case GraphQLMetricsServicePublishGraphQLMetricsProcedure: graphQLMetricsServicePublishGraphQLMetricsHandler.ServeHTTP(w, r) case GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure: graphQLMetricsServicePublishAggregatedGraphQLMetricsHandler.ServeHTTP(w, r) + case GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure: + graphQLMetricsServicePublishNormalizationCacheWarmupDataHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -150,3 +177,7 @@ func (UnimplementedGraphQLMetricsServiceHandler) PublishGraphQLMetrics(context.C func (UnimplementedGraphQLMetricsServiceHandler) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics is not implemented")) } + +func (UnimplementedGraphQLMetricsServiceHandler) PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData is not implemented")) +} diff --git a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto index 29800621ac..d327513024 100644 --- a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto +++ b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto @@ -27,10 +27,10 @@ message SchemaUsageInfo { SchemaInfo SchemaInfo = 4; // ClientInfo is the client info ClientInfo ClientInfo = 5; - // RequestInfo is the request info + // RequestInfo is the request info RequestInfo RequestInfo = 6; // Attributes is a map of attributes that can be used to filter the metrics - map Attributes = 7; + map Attributes = 7; // ArgumentMetrics is the list of used arguments in the request document repeated ArgumentUsageInfo ArgumentMetrics = 8; // InputMetrics is the list of used input fields in the request document @@ -38,8 +38,8 @@ message SchemaUsageInfo { } message SchemaUsageInfoAggregation { - SchemaUsageInfo SchemaUsage = 1; - uint64 RequestCount = 2; + SchemaUsageInfo SchemaUsage = 1; + uint64 RequestCount = 2; } message ClientInfo { @@ -118,8 +118,40 @@ message PublishAggregatedGraphQLRequestMetricsRequest { message PublishAggregatedGraphQLRequestMetricsResponse { } +message NormalizationCacheWarmupData { + NormalizationCacheWarmupDataQuery query = 1; + bool Encrypted = 3; + map VariableVariations = 4; +} + +message NormalizationCacheWarmupDataQuery { + string Query = 1; + uint64 Hash = 2; +} + +message VariableVariation { + repeated VariableValue VariableValues = 1; +} + +message VariableValue { + string Key = 1; + bool Value = 2; +} + +message NormalizationCacheWarmupDataAggregation { + map Operations = 1; +} + +message PublishNormalizationCacheWarmupDataRequest { + NormalizationCacheWarmupDataAggregation Aggregation = 1; +} + +message PublishNormalizationCacheWarmupDataResponse { +} + service GraphQLMetricsService { // PublishGraphQLMetrics publishes the GraphQL metrics to the metrics service rpc PublishGraphQLMetrics(PublishGraphQLRequestMetricsRequest) returns (PublishOperationCoverageReportResponse) {} rpc PublishAggregatedGraphQLMetrics(PublishAggregatedGraphQLRequestMetricsRequest) returns (PublishAggregatedGraphQLRequestMetricsResponse) {} + rpc PublishNormalizationCacheWarmupData(PublishNormalizationCacheWarmupDataRequest) returns (PublishNormalizationCacheWarmupDataResponse) {} } \ No newline at end of file diff --git a/router-tests/graphql_metrics_test.go b/router-tests/graphql_metrics_test.go index 3d17a28a4b..fef010bd5c 100644 --- a/router-tests/graphql_metrics_test.go +++ b/router-tests/graphql_metrics_test.go @@ -2,6 +2,7 @@ package integration import ( "compress/gzip" + "encoding/json" "io" "net/http" "net/http/httptest" @@ -12,6 +13,7 @@ import ( "github.com/wundergraph/cosmo/router-tests/testenv" "github.com/wundergraph/cosmo/router/core" graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" + "go.uber.org/zap" "google.golang.org/protobuf/proto" ) @@ -20,64 +22,113 @@ func TestGraphQLMetrics(t *testing.T) { waitForMetrics := make(chan struct{}) - var ( - data []byte - request graphqlmetrics.PublishAggregatedGraphQLRequestMetricsRequest - ) - fakeGraphQLMetricsServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { read, err := gzip.NewReader(r.Body) require.NoError(t, err) defer read.Close() - data, err = io.ReadAll(read) + data, err := io.ReadAll(read) require.NoError(t, err) - res := &graphqlmetrics.PublishAggregatedGraphQLRequestMetricsResponse{} - out, err := proto.Marshal(res) - require.NoError(t, err) + switch r.URL.Path { + case "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishNormalizationCacheWarmupData": - w.Header().Set("Content-Type", "application/proto") - _, err = w.Write(out) - require.NoError(t, err) + req := &graphqlmetrics.PublishNormalizationCacheWarmupDataRequest{} + err := proto.Unmarshal(data, req) + require.NoError(t, err) + require.Len(t, req.Aggregation.Operations, 1) + for _, v := range req.Aggregation.Operations { + require.Len(t, v.VariableVariations, 1) + for _, v := range v.VariableVariations { + require.Len(t, v.VariableValues, 2) + require.Equal(t, "include", v.VariableValues[0].Key) + require.Equal(t, true, v.VariableValues[0].Value) + require.Equal(t, "skip", v.VariableValues[1].Key) + require.Equal(t, false, v.VariableValues[1].Value) + } + } + + res := &graphqlmetrics.PublishNormalizationCacheWarmupDataResponse{} + out, err := proto.Marshal(res) + require.NoError(t, err) + + w.Header().Set("Content-Type", "application/proto") + _, err = w.Write(out) + require.NoError(t, err) + + waitForMetrics <- struct{}{} + + case "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishAggregatedGraphQLMetrics": + + req := &graphqlmetrics.PublishAggregatedGraphQLRequestMetricsRequest{} + err := proto.Unmarshal(data, req) + require.NoError(t, err) - close(waitForMetrics) + res := &graphqlmetrics.PublishAggregatedGraphQLRequestMetricsResponse{} + out, err := proto.Marshal(res) + require.NoError(t, err) + + w.Header().Set("Content-Type", "application/proto") + _, err = w.Write(out) + require.NoError(t, err) + + waitForMetrics <- struct{}{} + } })) + logger, err := zap.NewDevelopment() + require.NoError(t, err) + testenv.Run(t, &testenv.Config{ RouterOptions: []core.Option{ core.WithGraphQLMetrics(&core.GraphQLMetricsConfig{ Enabled: true, CollectorEndpoint: fakeGraphQLMetricsServer.URL, + // we only expect 2 operations, so we can immediately send the data to keep the test as fast as possible + BatchSize: 2, + BatchInterval: time.Second, }), - //core.WithAwsLambdaRuntime(), + core.WithLogger(logger), }, }, func(t *testing.T, xEnv *testenv.Environment) { res := xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ - Query: `query { employees { id } }`, + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { + employees { + id + details { + nationality + forename @include(if: $include) + surname @skip(if: $skip) + } + } + }`, + Variables: json.RawMessage(`{"include": true, "skip": false}`), }) - require.JSONEq(t, employeesIDData, res.Body) - + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David","surname":"Stutt"}}]}}`, res.Body) res = xEnv.MakeGraphQLRequestOK(testenv.GraphQLRequest{ - Query: `query { employees { id } }`, + Query: `query IncludeQuery($include: Boolean!, $skip: Boolean!) { + employees { + id + details { + nationality + forename @include(if: $include) + surname @skip(if: $skip) + } + } + }`, + Variables: json.RawMessage(`{"skip": false, "include": true}`), }) - require.JSONEq(t, employeesIDData, res.Body) + require.Equal(t, `{"data":{"employees":[{"id":1,"details":{"nationality":"GERMAN","forename":"Jens","surname":"Neuse"}},{"id":2,"details":{"nationality":"GERMAN","forename":"Dustin","surname":"Deus"}},{"id":3,"details":{"nationality":"AMERICAN","forename":"Stefan","surname":"Avram"}},{"id":4,"details":{"nationality":"GERMAN","forename":"Björn","surname":"Schwenzer"}},{"id":5,"details":{"nationality":"UKRAINIAN","forename":"Sergiy","surname":"Petrunin"}},{"id":7,"details":{"nationality":"INDIAN","forename":"Suvij","surname":"Surya"}},{"id":8,"details":{"nationality":"INDIAN","forename":"Nithin","surname":"Kumar"}},{"id":10,"details":{"nationality":"DUTCH","forename":"Eelco","surname":"Wiersma"}},{"id":11,"details":{"nationality":"GERMAN","forename":"Alexandra","surname":"Neuse"}},{"id":12,"details":{"nationality":"ENGLISH","forename":"David","surname":"Stutt"}}]}}`, res.Body) }) - select { - case <-waitForMetrics: - case <-time.After(60 * time.Second): - t.Fatal("timeout waiting for metrics") + timeout := time.After(5 * time.Second) + + for i := 0; i < 2; i++ { + select { + case <-waitForMetrics: + case <-timeout: + t.Fatal("timeout waiting for metrics") + } } - err := proto.Unmarshal(data, &request) - require.NoError(t, err) - require.Len(t, request.Aggregation, 1) - require.Equal(t, uint64(2), request.Aggregation[0].RequestCount) - require.Equal(t, "{employees {id}}", request.Aggregation[0].SchemaUsage.RequestDocument) - require.Equal(t, int32(200), request.Aggregation[0].SchemaUsage.RequestInfo.StatusCode) - require.Equal(t, "1163600561566987607", request.Aggregation[0].SchemaUsage.OperationInfo.Hash) - require.Equal(t, graphqlmetrics.OperationType_QUERY, request.Aggregation[0].SchemaUsage.OperationInfo.Type) - require.Len(t, request.Aggregation[0].SchemaUsage.TypeFieldMetrics, 2) - require.Equal(t, []string{"employees"}, request.Aggregation[0].SchemaUsage.TypeFieldMetrics[0].Path) } diff --git a/router/cmd/instance.go b/router/cmd/instance.go index c18af92004..966561acd5 100644 --- a/router/cmd/instance.go +++ b/router/cmd/instance.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "os" + "time" "github.com/KimMachineGun/automemlimit/memlimit" "github.com/dustin/go-humanize" @@ -120,6 +121,21 @@ func NewRouter(ctx context.Context, params Params, additionalOptions ...core.Opt core.WithGraphQLMetrics(&core.GraphQLMetricsConfig{ Enabled: cfg.GraphqlMetrics.Enabled, CollectorEndpoint: cfg.GraphqlMetrics.CollectorEndpoint, + BatchSize: cfg.GraphqlMetrics.BatchSize, + BatchInterval: cfg.GraphqlMetrics.BatchInterval, + QueueSize: cfg.GraphqlMetrics.QueueSize, + ExportTimeout: cfg.GraphqlMetrics.ExportTimeout, + RetryOptions: struct { + Enabled bool + MaxDuration time.Duration + Interval time.Duration + MaxAttempts int + }{ + Enabled: cfg.GraphqlMetrics.RetryOptions.Enabled, + MaxAttempts: cfg.GraphqlMetrics.RetryOptions.MaxAttempts, + Interval: cfg.GraphqlMetrics.RetryOptions.Interval, + MaxDuration: cfg.GraphqlMetrics.RetryOptions.MaxDuration, + }, }), core.WithAnonymization(&core.IPAnonymizationConfig{ Enabled: cfg.Compliance.AnonymizeIP.Enabled, diff --git a/router/core/context.go b/router/core/context.go index 716b3dfb82..55686fca2a 100644 --- a/router/core/context.go +++ b/router/core/context.go @@ -496,9 +496,10 @@ type operationContext struct { persistedOperationCacheHit bool normalizationCacheHit bool - typeFieldUsageInfo []*graphqlmetrics.TypeFieldUsageInfo - argumentUsageInfo []*graphqlmetrics.ArgumentUsageInfo - inputUsageInfo []*graphqlmetrics.InputUsageInfo + typeFieldUsageInfo []*graphqlmetrics.TypeFieldUsageInfo + argumentUsageInfo []*graphqlmetrics.ArgumentUsageInfo + inputUsageInfo []*graphqlmetrics.InputUsageInfo + normalizationWarmupData *graphqlmetrics.NormalizationCacheWarmupData parsingTime time.Duration validationTime time.Duration diff --git a/router/core/graph_server.go b/router/core/graph_server.go index fa30d261c2..d7d29379dd 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -643,11 +643,12 @@ func (s *graphServer) buildGraphMux(ctx context.Context, } metrics := NewRouterMetrics(&routerMetricsConfig{ - metrics: gm.metricStore, - gqlMetricsExporter: s.gqlMetricsExporter, - exportEnabled: s.graphqlMetricsConfig.Enabled, - routerConfigVersion: routerConfigVersion, - logger: s.logger, + metrics: gm.metricStore, + gqlMetricsExporter: s.gqlMetricsExporter, + normalizationCacheWarmupExporter: s.normalizationCacheWarmupExporter, + exportEnabled: s.graphqlMetricsConfig.Enabled, + routerConfigVersion: routerConfigVersion, + logger: s.logger, }) baseLogFields := []zapcore.Field{ diff --git a/router/core/graphql_prehandler.go b/router/core/graphql_prehandler.go index 946adaef37..cd0e8c1760 100644 --- a/router/core/graphql_prehandler.go +++ b/router/core/graphql_prehandler.go @@ -486,6 +486,10 @@ func (h *PreHandler) handleOperation(req *http.Request, variablesParser *astjson return err } + if h.trackSchemaUsageInfo { + requestContext.operation.normalizationWarmupData = operationKit.ExtractNormalizationCacheWarmupData() + } + requestContext.operation.parsingTime = time.Since(startParsing) if !requestContext.operation.traceOptions.ExcludeParseStats { httpOperation.traceTimings.EndParse() diff --git a/router/core/operation_processor.go b/router/core/operation_processor.go index b33377ccb8..5522501e49 100644 --- a/router/core/operation_processor.go +++ b/router/core/operation_processor.go @@ -19,7 +19,8 @@ import ( "github.com/dgraph-io/ristretto" "github.com/pkg/errors" "github.com/tidwall/sjson" - fastjson "github.com/wundergraph/astjson" + "github.com/wundergraph/astjson" + graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" "github.com/wundergraph/graphql-go-tools/v2/pkg/apollocompatibility" "github.com/wundergraph/graphql-go-tools/v2/pkg/ast" @@ -55,7 +56,7 @@ type ParsedOperation struct { // Type is a string representing the operation type. One of // "query", "mutation", "subscription" Type string - Variables *fastjson.Object + Variables *astjson.Object RemapVariables map[string]string // Files is a list of files, an interface representing the file data needed to be passed forward. Files []httpclient.File @@ -311,7 +312,7 @@ func (o *OperationKit) unmarshalOperation() error { if o.parsedOperation.Request.Variables != nil { // variables must be a valid JSON object or null - variables, err := fastjson.ParseBytes(o.parsedOperation.Request.Variables) + variables, err := astjson.ParseBytes(o.parsedOperation.Request.Variables) if err != nil { return &httpGraphqlError{ message: fmt.Sprintf("error parsing variables: %s", err), @@ -319,12 +320,12 @@ func (o *OperationKit) unmarshalOperation() error { } } switch variables.Type() { - case fastjson.TypeNull: + case astjson.TypeNull: // set variables to empty object if they are null, so we can later add exported defaults // also, other parts of the engine depend on variables being a valid JSON object o.parsedOperation.Request.Variables = []byte("{}") - o.parsedOperation.Variables = fastjson.MustParseBytes(o.parsedOperation.Request.Variables).GetObject() - case fastjson.TypeObject: + o.parsedOperation.Variables = astjson.MustParseBytes(o.parsedOperation.Request.Variables).GetObject() + case astjson.TypeObject: o.parsedOperation.Variables = variables.GetObject() default: return &httpGraphqlError{ @@ -336,7 +337,7 @@ func (o *OperationKit) unmarshalOperation() error { // set variables to empty object if they are null, so we can later add exported defaults // also, other parts of the engine depend on variables being a valid JSON object o.parsedOperation.Request.Variables = []byte("{}") - o.parsedOperation.Variables = fastjson.MustParseBytes(o.parsedOperation.Request.Variables).GetObject() + o.parsedOperation.Variables = astjson.MustParseBytes(o.parsedOperation.Request.Variables).GetObject() } // we're doing string matching on the operation name, so we override null with empty string @@ -381,7 +382,7 @@ func (o *OperationKit) ComputeOperationSha256() error { // FetchPersistedOperation fetches the persisted operation from the cache or the client. If the operation is fetched from the cache it returns true. // UnmarshalOperationFromBody or UnmarshalOperationFromURL must be called before calling this method. -func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *ClientInfo) (bool, bool, error) { +func (o *OperationKit) FetchPersistedOperation(ctx context.Context, clientInfo *ClientInfo) (skipParse bool, isAPQ bool, err error) { if o.operationProcessor.persistedOperationClient == nil { return false, false, &httpGraphqlError{ message: "could not resolve persisted query, feature is not configured", @@ -615,6 +616,56 @@ func (o *OperationKit) Parse() error { return nil } +func (o *OperationKit) ExtractNormalizationCacheWarmupData() *graphqlmetricsv1.NormalizationCacheWarmupData { + _, _ = o.kit.keyGen.WriteString(o.parsedOperation.Request.Query) + out := &graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: o.parsedOperation.Request.Query, + Hash: o.kit.keyGen.Sum64(), + }, + VariableVariations: make(map[uint64]*graphqlmetricsv1.VariableVariation, 1), + Encrypted: false, + } + o.kit.keyGen.Reset() + variables := o.skipIncludeVariableNames() + variation := &graphqlmetricsv1.VariableVariation{ + VariableValues: make([]*graphqlmetricsv1.VariableValue, 0, len(variables)), + } + if len(variables) != 0 { + slices.Sort(variables) // sort the variables to ensure a consistent order + for _, key := range variables { + _, _ = o.kit.keyGen.WriteString(key) + value := o.parsedOperation.Variables.Get(key) + if value == nil { + _, _ = o.kit.keyGen.WriteString("n") + continue + } + if value.Type() == astjson.TypeTrue { + variation.VariableValues = append(variation.VariableValues, &graphqlmetricsv1.VariableValue{ + Key: key, + Value: true, + }) + _, _ = o.kit.keyGen.WriteString("t") + continue + } + if value.Type() == astjson.TypeFalse { + variation.VariableValues = append(variation.VariableValues, &graphqlmetricsv1.VariableValue{ + Key: key, + Value: false, + }) + _, _ = o.kit.keyGen.WriteString("f") + continue + } else { + _, _ = o.kit.keyGen.WriteString("s") + } + } + } + key := o.kit.keyGen.Sum64() + out.VariableVariations[key] = variation + o.kit.keyGen.Reset() + return out +} + // NormalizeOperation normalizes the operation. After normalization the normalized representation of the operation // and variables is available. Also, the final operation ID is generated. func (o *OperationKit) NormalizeOperation(clientName string, isApq bool) (bool, error) { @@ -918,11 +969,11 @@ func (o *OperationKit) jsonIsNull(variables []byte) bool { if len(variables) == 4 && unsafebytes.BytesToString(variables) == "null" { return true } - value, err := fastjson.ParseBytes(variables) + value, err := astjson.ParseBytes(variables) if err != nil { return false } - return value.Type() == fastjson.TypeNull + return value.Type() == astjson.TypeNull } func (o *OperationKit) persistedOperationCacheKeyHasTtl(clientName string, includeOperationName bool) (bool, []string) { @@ -998,16 +1049,16 @@ func (o *OperationKit) writeSkipIncludeCacheKeyToKeyGen(skipIncludeVariableNames for i := range skipIncludeVariableNames { value := o.parsedOperation.Variables.Get(skipIncludeVariableNames[i]) if value == nil { - _, _ = o.kit.keyGen.WriteString("x") + _, _ = o.kit.keyGen.WriteString("n") continue } switch value.Type() { - case fastjson.TypeTrue: + case astjson.TypeTrue: _, _ = o.kit.keyGen.WriteString("t") - case fastjson.TypeFalse: + case astjson.TypeFalse: _, _ = o.kit.keyGen.WriteString("f") default: - _, _ = o.kit.keyGen.WriteString("x") + _, _ = o.kit.keyGen.WriteString("s") } } } @@ -1085,7 +1136,7 @@ func (o *OperationKit) ValidateQueryComplexity(complexityLimitConfig *config.Com } func (o *OperationKit) runComplexityComparisons(complexityLimitConfig *config.ComplexityLimits, cachedComplexity ComplexityCacheEntry, isPersisted bool) error { - testComparisons := []complexityComparison{} + var testComparisons []complexityComparison if complexityLimitConfig.Depth != nil && complexityLimitConfig.Depth.ApplyLimit(isPersisted) { testComparisons = append(testComparisons, complexityComparison{complexityLimitConfig.Depth.Limit, cachedComplexity.Depth, fmt.Sprintf("The query depth %d exceeds the max query depth allowed (%d)", cachedComplexity.Depth, complexityLimitConfig.Depth.Limit)}) diff --git a/router/core/router.go b/router/core/router.go index ac37f2fef7..95b220429f 100644 --- a/router/core/router.go +++ b/router/core/router.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/wundergraph/cosmo/router/internal/exporter" + "github.com/wundergraph/cosmo/router/internal/normalizationcachewarmupexporter" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/propagation" @@ -107,6 +109,16 @@ type ( GraphQLMetricsConfig struct { Enabled bool CollectorEndpoint string + BatchSize int + BatchInterval time.Duration + QueueSize int + ExportTimeout time.Duration + RetryOptions struct { + Enabled bool + MaxDuration time.Duration + Interval time.Duration + MaxAttempts int + } } IPAnonymizationConfig struct { @@ -148,62 +160,63 @@ type ( // Config defines the configuration options for the Router. Config struct { - clusterName string - instanceID string - logger *zap.Logger - traceConfig *rtrace.Config - metricConfig *rmetric.Config - tracerProvider *sdktrace.TracerProvider - otlpMeterProvider *sdkmetric.MeterProvider - promMeterProvider *sdkmetric.MeterProvider - gqlMetricsExporter *graphqlmetrics.Exporter - corsOptions *cors.Config - setConfigVersionHeader bool - routerGracePeriod time.Duration - staticExecutionConfig *nodev1.RouterConfig - awsLambda bool - shutdown atomic.Bool - bootstrapped atomic.Bool - ipAnonymization *IPAnonymizationConfig - listenAddr string - baseURL string - graphqlWebURL string - playgroundPath string - graphqlPath string - playground bool - introspection bool - queryPlansEnabled bool - graphApiToken string - healthCheckPath string - readinessCheckPath string - livenessCheckPath string - cacheControlPolicy config.CacheControlPolicy - routerConfigPollerConfig *RouterConfigPollerConfig - cdnConfig config.CDNConfiguration - persistedOperationClient persistedoperation.SaveClient - persistedOperationsConfig config.PersistedOperationsConfig - automaticPersistedQueriesConfig config.AutomaticPersistedQueriesConfig - apolloCompatibilityFlags config.ApolloCompatibilityFlags - storageProviders config.StorageProviders - eventsConfig config.EventsConfiguration - prometheusServer *http.Server - modulesConfig map[string]interface{} - executionConfig *ExecutionConfig - routerMiddlewares []func(http.Handler) http.Handler - preOriginHandlers []TransportPreHandler - postOriginHandlers []TransportPostHandler - headerRules *config.HeaderRules - subgraphTransportOptions *SubgraphTransportOptions - graphqlMetricsConfig *GraphQLMetricsConfig - routerTrafficConfig *config.RouterTrafficConfiguration - fileUploadConfig *config.FileUpload - accessController *AccessController - retryOptions retrytransport.RetryOptions - redisClient *redis.Client - processStartTime time.Time - developmentMode bool - healthcheck health.Checker - accessLogsConfig *AccessLogsConfig + clusterName string + instanceID string + logger *zap.Logger + traceConfig *rtrace.Config + metricConfig *rmetric.Config + tracerProvider *sdktrace.TracerProvider + otlpMeterProvider *sdkmetric.MeterProvider + promMeterProvider *sdkmetric.MeterProvider + gqlMetricsExporter *graphqlmetrics.Exporter + normalizationCacheWarmupExporter *normalizationcachewarmupexporter.Exporter + corsOptions *cors.Config + setConfigVersionHeader bool + routerGracePeriod time.Duration + staticExecutionConfig *nodev1.RouterConfig + awsLambda bool + shutdown atomic.Bool + bootstrapped atomic.Bool + ipAnonymization *IPAnonymizationConfig + listenAddr string + baseURL string + graphqlWebURL string + playgroundPath string + graphqlPath string + playground bool + introspection bool + queryPlansEnabled bool + graphApiToken string + healthCheckPath string + readinessCheckPath string + livenessCheckPath string + cacheControlPolicy config.CacheControlPolicy + routerConfigPollerConfig *RouterConfigPollerConfig + cdnConfig config.CDNConfiguration + persistedOperationClient persistedoperation.SaveClient + persistedOperationsConfig config.PersistedOperationsConfig + automaticPersistedQueriesConfig config.AutomaticPersistedQueriesConfig + apolloCompatibilityFlags config.ApolloCompatibilityFlags + storageProviders config.StorageProviders + eventsConfig config.EventsConfiguration + prometheusServer *http.Server + modulesConfig map[string]interface{} + executionConfig *ExecutionConfig + routerMiddlewares []func(http.Handler) http.Handler + preOriginHandlers []TransportPreHandler + postOriginHandlers []TransportPostHandler + headerRules *config.HeaderRules + subgraphTransportOptions *SubgraphTransportOptions + graphqlMetricsConfig *GraphQLMetricsConfig + routerTrafficConfig *config.RouterTrafficConfiguration + fileUploadConfig *config.FileUpload + accessController *AccessController + retryOptions retrytransport.RetryOptions + redisClient *redis.Client + processStartTime time.Time + developmentMode bool + healthcheck health.Checker + accessLogsConfig *AccessLogsConfig // If connecting to localhost inside Docker fails, fallback to the docker internal address for the host localhostFallbackInsideDocker bool tlsServerConfig *tls.Config @@ -818,22 +831,46 @@ func (r *Router) bootstrap(ctx context.Context) error { } if r.graphqlMetricsConfig.Enabled { + + settings := exporter.NewSettings( + r.graphqlMetricsConfig.BatchSize, + r.graphqlMetricsConfig.QueueSize, + r.graphqlMetricsConfig.BatchInterval, + r.graphqlMetricsConfig.ExportTimeout, + r.graphqlMetricsConfig.RetryOptions.Enabled, + r.graphqlMetricsConfig.RetryOptions.MaxAttempts, + r.graphqlMetricsConfig.RetryOptions.MaxDuration, + r.graphqlMetricsConfig.RetryOptions.Interval, + ) + client := graphqlmetricsv1connect.NewGraphQLMetricsServiceClient( http.DefaultClient, r.graphqlMetricsConfig.CollectorEndpoint, connect.WithSendGzip(), ) + ge, err := graphqlmetrics.NewExporter( r.logger, client, r.graphApiToken, - graphqlmetrics.NewDefaultExporterSettings(), + settings, ) if err != nil { return fmt.Errorf("failed to validate graphql metrics exporter: %w", err) } r.gqlMetricsExporter = ge + ne, err := normalizationcachewarmupexporter.NewExporter( + r.logger, + client, + r.graphApiToken, + settings, + ) + if err != nil { + return fmt.Errorf("failed to validate normalization cache warmup exporter: %w", err) + } + r.normalizationCacheWarmupExporter = ne + r.logger.Info("GraphQL schema coverage metrics enabled") } @@ -1655,6 +1692,21 @@ func DefaultGraphQLMetricsConfig() *GraphQLMetricsConfig { return &GraphQLMetricsConfig{ Enabled: false, CollectorEndpoint: "", + BatchSize: 1024, + BatchInterval: 10 * time.Second, + QueueSize: 1024, + ExportTimeout: time.Second * 10, + RetryOptions: struct { + Enabled bool + MaxDuration time.Duration + Interval time.Duration + MaxAttempts int + }{ + Enabled: true, + MaxDuration: time.Second * 5, + Interval: time.Second, *5, + MaxAttempts: 5, + }, } } diff --git a/router/core/router_metrics.go b/router/core/router_metrics.go index 5a3c4c68a1..9631760c5f 100644 --- a/router/core/router_metrics.go +++ b/router/core/router_metrics.go @@ -1,9 +1,11 @@ package core import ( + "strconv" + + "github.com/wundergraph/cosmo/router/internal/normalizationcachewarmupexporter" "go.opentelemetry.io/otel/attribute" otelmetric "go.opentelemetry.io/otel/metric" - "strconv" graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" "github.com/wundergraph/cosmo/router/internal/graphqlmetrics" @@ -22,28 +24,31 @@ type RouterMetrics interface { // routerMetrics encapsulates all data and configuration that the router // uses to collect and its metrics type routerMetrics struct { - metrics metric.Store - gqlMetricsExporter *graphqlmetrics.Exporter - routerConfigVersion string - logger *zap.Logger - exportEnabled bool + metrics metric.Store + gqlMetricsExporter *graphqlmetrics.Exporter + normalizationCacheWarmupExporter *normalizationcachewarmupexporter.Exporter + routerConfigVersion string + logger *zap.Logger + exportEnabled bool } type routerMetricsConfig struct { - metrics metric.Store - gqlMetricsExporter *graphqlmetrics.Exporter - routerConfigVersion string - logger *zap.Logger - exportEnabled bool + metrics metric.Store + gqlMetricsExporter *graphqlmetrics.Exporter + normalizationCacheWarmupExporter *normalizationcachewarmupexporter.Exporter + routerConfigVersion string + logger *zap.Logger + exportEnabled bool } func NewRouterMetrics(cfg *routerMetricsConfig) RouterMetrics { return &routerMetrics{ - metrics: cfg.metrics, - gqlMetricsExporter: cfg.gqlMetricsExporter, - routerConfigVersion: cfg.routerConfigVersion, - logger: cfg.logger, - exportEnabled: cfg.exportEnabled, + metrics: cfg.metrics, + gqlMetricsExporter: cfg.gqlMetricsExporter, + normalizationCacheWarmupExporter: cfg.normalizationCacheWarmupExporter, + routerConfigVersion: cfg.routerConfigVersion, + logger: cfg.logger, + exportEnabled: cfg.exportEnabled, } } @@ -121,6 +126,9 @@ func (m *routerMetrics) ExportSchemaUsageInfo(operationContext *operationContext } m.gqlMetricsExporter.RecordUsage(item, exportSynchronous) + if operationContext.normalizationWarmupData != nil { + m.normalizationCacheWarmupExporter.RecordUsage(operationContext.normalizationWarmupData, exportSynchronous) + } } func (m *routerMetrics) strCopy(s string) string { diff --git a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index 7127c79946..0b1b972e94 100644 --- a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -895,6 +895,358 @@ func (*PublishAggregatedGraphQLRequestMetricsResponse) Descriptor() ([]byte, []i return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{12} } +type NormalizationCacheWarmupData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query *NormalizationCacheWarmupDataQuery `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"` + Encrypted bool `protobuf:"varint,3,opt,name=Encrypted,proto3" json:"Encrypted,omitempty"` + VariableVariations map[uint64]*VariableVariation `protobuf:"bytes,4,rep,name=VariableVariations,proto3" json:"VariableVariations,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *NormalizationCacheWarmupData) Reset() { + *x = NormalizationCacheWarmupData{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupData) ProtoMessage() {} + +func (x *NormalizationCacheWarmupData) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13] + 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 NormalizationCacheWarmupData.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupData) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{13} +} + +func (x *NormalizationCacheWarmupData) GetQuery() *NormalizationCacheWarmupDataQuery { + if x != nil { + return x.Query + } + return nil +} + +func (x *NormalizationCacheWarmupData) GetEncrypted() bool { + if x != nil { + return x.Encrypted + } + return false +} + +func (x *NormalizationCacheWarmupData) GetVariableVariations() map[uint64]*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type NormalizationCacheWarmupDataQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` + Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` +} + +func (x *NormalizationCacheWarmupDataQuery) Reset() { + *x = NormalizationCacheWarmupDataQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupDataQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupDataQuery) ProtoMessage() {} + +func (x *NormalizationCacheWarmupDataQuery) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14] + 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 NormalizationCacheWarmupDataQuery.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupDataQuery) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{14} +} + +func (x *NormalizationCacheWarmupDataQuery) GetQuery() string { + if x != nil { + return x.Query + } + return "" +} + +func (x *NormalizationCacheWarmupDataQuery) GetHash() uint64 { + if x != nil { + return x.Hash + } + return 0 +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + VariableValues []*VariableValue `protobuf:"bytes,1,rep,name=VariableValues,proto3" json:"VariableValues,omitempty"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{15} +} + +func (x *VariableVariation) GetVariableValues() []*VariableValue { + if x != nil { + return x.VariableValues + } + return nil +} + +type VariableValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"` + Value bool `protobuf:"varint,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *VariableValue) Reset() { + *x = VariableValue{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableValue) ProtoMessage() {} + +func (x *VariableValue) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16] + 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 VariableValue.ProtoReflect.Descriptor instead. +func (*VariableValue) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{16} +} + +func (x *VariableValue) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *VariableValue) GetValue() bool { + if x != nil { + return x.Value + } + return false +} + +type NormalizationCacheWarmupDataAggregation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Operations map[uint64]*NormalizationCacheWarmupData `protobuf:"bytes,1,rep,name=Operations,proto3" json:"Operations,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *NormalizationCacheWarmupDataAggregation) Reset() { + *x = NormalizationCacheWarmupDataAggregation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NormalizationCacheWarmupDataAggregation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NormalizationCacheWarmupDataAggregation) ProtoMessage() {} + +func (x *NormalizationCacheWarmupDataAggregation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17] + 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 NormalizationCacheWarmupDataAggregation.ProtoReflect.Descriptor instead. +func (*NormalizationCacheWarmupDataAggregation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{17} +} + +func (x *NormalizationCacheWarmupDataAggregation) GetOperations() map[uint64]*NormalizationCacheWarmupData { + if x != nil { + return x.Operations + } + return nil +} + +type PublishNormalizationCacheWarmupDataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Aggregation *NormalizationCacheWarmupDataAggregation `protobuf:"bytes,1,opt,name=Aggregation,proto3" json:"Aggregation,omitempty"` +} + +func (x *PublishNormalizationCacheWarmupDataRequest) Reset() { + *x = PublishNormalizationCacheWarmupDataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishNormalizationCacheWarmupDataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishNormalizationCacheWarmupDataRequest) ProtoMessage() {} + +func (x *PublishNormalizationCacheWarmupDataRequest) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18] + 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 PublishNormalizationCacheWarmupDataRequest.ProtoReflect.Descriptor instead. +func (*PublishNormalizationCacheWarmupDataRequest) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{18} +} + +func (x *PublishNormalizationCacheWarmupDataRequest) GetAggregation() *NormalizationCacheWarmupDataAggregation { + if x != nil { + return x.Aggregation + } + return nil +} + +type PublishNormalizationCacheWarmupDataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PublishNormalizationCacheWarmupDataResponse) Reset() { + *x = PublishNormalizationCacheWarmupDataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishNormalizationCacheWarmupDataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishNormalizationCacheWarmupDataResponse) ProtoMessage() {} + +func (x *PublishNormalizationCacheWarmupDataResponse) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19] + 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 PublishNormalizationCacheWarmupDataResponse.ProtoReflect.Descriptor instead. +func (*PublishNormalizationCacheWarmupDataResponse) Descriptor() ([]byte, []int) { + return file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP(), []int{19} +} + var File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto protoreflect.FileDescriptor var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ @@ -1032,53 +1384,134 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc = []byte{ 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x30, 0x0a, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, - 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x09, 0x0a, 0x05, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, - 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, - 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xf5, 0x02, 0x0a, 0x15, 0x47, - 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, - 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8a, + 0x03, 0x0a, 0x1c, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x53, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, - 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x42, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x73, 0x68, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, - 0x65, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xba, 0x01, 0x0a, 0x1f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, - 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, - 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x49, 0x2e, 0x77, 0x67, 0x2e, 0x63, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, + 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, + 0x65, 0x64, 0x12, 0x80, 0x01, 0x0a, 0x12, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x50, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, + 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x12, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x74, 0x0a, 0x17, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x43, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, 0x0a, 0x21, 0x4e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, + 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x48, 0x61, 0x73, 0x68, 0x22, 0x66, 0x0a, 0x11, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x51, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x22, 0x37, 0x0a, 0x0d, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x97, 0x02, 0x0a, 0x27, + 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, + 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x73, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x53, 0x2e, 0x77, 0x67, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, + 0x70, 0x44, 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x77, 0x0a, 0x0f, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x38, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x2a, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x0b, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x4a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, - 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x9b, 0x02, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, - 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x59, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, - 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, - 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, - 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, + 0x61, 0x74, 0x61, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2d, 0x0a, 0x2b, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3a, 0x0a, 0x0d, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x51, + 0x55, 0x45, 0x52, 0x59, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x55, 0x54, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x32, 0xb0, 0x04, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x51, 0x4c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x3f, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x42, 0x2e, 0x77, 0x67, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0xba, 0x01, 0x0a, 0x1f, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x4d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x49, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x64, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x4a, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x47, + 0x72, 0x61, 0x70, 0x68, 0x51, 0x4c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0xb8, + 0x01, 0x0a, 0x23, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, + 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x12, 0x46, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, + 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x47, + 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x71, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x43, 0x61, 0x63, 0x68, 0x65, 0x57, 0x61, 0x72, 0x6d, 0x75, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x9b, 0x02, 0x0a, 0x1e, 0x63, 0x6f, + 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x59, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x76, 0x31, 0xa2, 0x02, + 0x03, 0x57, 0x43, 0x47, 0xaa, 0x02, 0x1a, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x56, + 0x31, 0xca, 0x02, 0x1a, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, + 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x26, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, + 0x6c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x47, 0x72, 0x61, 0x70, 0x68, 0x71, 0x6c, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1094,7 +1527,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDescGZIP() []byte { } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []any{ (OperationType)(0), // 0: wg.cosmo.graphqlmetrics.v1.OperationType (*RequestInfo)(nil), // 1: wg.cosmo.graphqlmetrics.v1.RequestInfo @@ -1110,7 +1543,16 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_goTypes = []any{ (*PublishOperationCoverageReportResponse)(nil), // 11: wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse (*PublishAggregatedGraphQLRequestMetricsRequest)(nil), // 12: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest (*PublishAggregatedGraphQLRequestMetricsResponse)(nil), // 13: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse - nil, // 14: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + (*NormalizationCacheWarmupData)(nil), // 14: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData + (*NormalizationCacheWarmupDataQuery)(nil), // 15: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataQuery + (*VariableVariation)(nil), // 16: wg.cosmo.graphqlmetrics.v1.VariableVariation + (*VariableValue)(nil), // 17: wg.cosmo.graphqlmetrics.v1.VariableValue + (*NormalizationCacheWarmupDataAggregation)(nil), // 18: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation + (*PublishNormalizationCacheWarmupDataRequest)(nil), // 19: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest + (*PublishNormalizationCacheWarmupDataResponse)(nil), // 20: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataResponse + nil, // 21: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + nil, // 22: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry + nil, // 23: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry } var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ 7, // 0: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.TypeFieldMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.TypeFieldUsageInfo @@ -1118,22 +1560,31 @@ var file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_depIdxs = []int32{ 6, // 2: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.SchemaInfo:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaInfo 4, // 3: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ClientInfo:type_name -> wg.cosmo.graphqlmetrics.v1.ClientInfo 1, // 4: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.RequestInfo:type_name -> wg.cosmo.graphqlmetrics.v1.RequestInfo - 14, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry + 21, // 5: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.Attributes:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.AttributesEntry 8, // 6: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.ArgumentMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.ArgumentUsageInfo 9, // 7: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo.InputMetrics:type_name -> wg.cosmo.graphqlmetrics.v1.InputUsageInfo 2, // 8: wg.cosmo.graphqlmetrics.v1.SchemaUsageInfoAggregation.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo 0, // 9: wg.cosmo.graphqlmetrics.v1.OperationInfo.Type:type_name -> wg.cosmo.graphqlmetrics.v1.OperationType 2, // 10: wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest.SchemaUsage:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfo 3, // 11: wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest.Aggregation:type_name -> wg.cosmo.graphqlmetrics.v1.SchemaUsageInfoAggregation - 10, // 12: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest - 12, // 13: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest - 11, // 14: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse - 13, // 15: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse - 14, // [14:16] is the sub-list for method output_type - 12, // [12:14] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 15, // 12: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.query:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataQuery + 22, // 13: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariations:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry + 17, // 14: wg.cosmo.graphqlmetrics.v1.VariableVariation.VariableValues:type_name -> wg.cosmo.graphqlmetrics.v1.VariableValue + 23, // 15: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.Operations:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry + 18, // 16: wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest.Aggregation:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation + 16, // 17: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData.VariableVariationsEntry.value:type_name -> wg.cosmo.graphqlmetrics.v1.VariableVariation + 14, // 18: wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupDataAggregation.OperationsEntry.value:type_name -> wg.cosmo.graphqlmetrics.v1.NormalizationCacheWarmupData + 10, // 19: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishGraphQLRequestMetricsRequest + 12, // 20: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:input_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsRequest + 19, // 21: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData:input_type -> wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataRequest + 11, // 22: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishOperationCoverageReportResponse + 13, // 23: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics:output_type -> wg.cosmo.graphqlmetrics.v1.PublishAggregatedGraphQLRequestMetricsResponse + 20, // 24: wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData:output_type -> wg.cosmo.graphqlmetrics.v1.PublishNormalizationCacheWarmupDataResponse + 22, // [22:25] is the sub-list for method output_type + 19, // [19:22] is the sub-list for method input_type + 19, // [19:19] is the sub-list for extension type_name + 19, // [19:19] is the sub-list for extension extendee + 0, // [0:19] is the sub-list for field type_name } func init() { file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() } @@ -1298,6 +1749,90 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { return nil } } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupDataQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*VariableVariation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*VariableValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*NormalizationCacheWarmupDataAggregation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[18].Exporter = func(v any, i int) any { + switch v := v.(*PublishNormalizationCacheWarmupDataRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_msgTypes[19].Exporter = func(v any, i int) any { + switch v := v.(*PublishNormalizationCacheWarmupDataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1305,7 +1840,7 @@ func file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto_rawDesc, NumEnums: 1, - NumMessages: 14, + NumMessages: 23, NumExtensions: 0, NumServices: 1, }, diff --git a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go index 5d18cd3127..4f13ffa7f9 100644 --- a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go +++ b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect/graphqlmetrics.connect.go @@ -41,13 +41,17 @@ const ( // GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure is the fully-qualified name of the // GraphQLMetricsService's PublishAggregatedGraphQLMetrics RPC. GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure = "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishAggregatedGraphQLMetrics" + // GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure is the fully-qualified name of + // the GraphQLMetricsService's PublishNormalizationCacheWarmupData RPC. + GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure = "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/PublishNormalizationCacheWarmupData" ) // These variables are the protoreflect.Descriptor objects for the RPCs defined in this package. var ( - graphQLMetricsServiceServiceDescriptor = v1.File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto.Services().ByName("GraphQLMetricsService") - graphQLMetricsServicePublishGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishGraphQLMetrics") - graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishAggregatedGraphQLMetrics") + graphQLMetricsServiceServiceDescriptor = v1.File_wg_cosmo_graphqlmetrics_v1_graphqlmetrics_proto.Services().ByName("GraphQLMetricsService") + graphQLMetricsServicePublishGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishGraphQLMetrics") + graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishAggregatedGraphQLMetrics") + graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor = graphQLMetricsServiceServiceDescriptor.Methods().ByName("PublishNormalizationCacheWarmupData") ) // GraphQLMetricsServiceClient is a client for the wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService @@ -56,6 +60,7 @@ type GraphQLMetricsServiceClient interface { // PublishGraphQLMetrics publishes the GraphQL metrics to the metrics service PublishGraphQLMetrics(context.Context, *connect.Request[v1.PublishGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishOperationCoverageReportResponse], error) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) + PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) } // NewGraphQLMetricsServiceClient constructs a client for the @@ -81,13 +86,20 @@ func NewGraphQLMetricsServiceClient(httpClient connect.HTTPClient, baseURL strin connect.WithSchema(graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor), connect.WithClientOptions(opts...), ), + publishNormalizationCacheWarmupData: connect.NewClient[v1.PublishNormalizationCacheWarmupDataRequest, v1.PublishNormalizationCacheWarmupDataResponse]( + httpClient, + baseURL+GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure, + connect.WithSchema(graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor), + connect.WithClientOptions(opts...), + ), } } // graphQLMetricsServiceClient implements GraphQLMetricsServiceClient. type graphQLMetricsServiceClient struct { - publishGraphQLMetrics *connect.Client[v1.PublishGraphQLRequestMetricsRequest, v1.PublishOperationCoverageReportResponse] - publishAggregatedGraphQLMetrics *connect.Client[v1.PublishAggregatedGraphQLRequestMetricsRequest, v1.PublishAggregatedGraphQLRequestMetricsResponse] + publishGraphQLMetrics *connect.Client[v1.PublishGraphQLRequestMetricsRequest, v1.PublishOperationCoverageReportResponse] + publishAggregatedGraphQLMetrics *connect.Client[v1.PublishAggregatedGraphQLRequestMetricsRequest, v1.PublishAggregatedGraphQLRequestMetricsResponse] + publishNormalizationCacheWarmupData *connect.Client[v1.PublishNormalizationCacheWarmupDataRequest, v1.PublishNormalizationCacheWarmupDataResponse] } // PublishGraphQLMetrics calls @@ -102,12 +114,19 @@ func (c *graphQLMetricsServiceClient) PublishAggregatedGraphQLMetrics(ctx contex return c.publishAggregatedGraphQLMetrics.CallUnary(ctx, req) } +// PublishNormalizationCacheWarmupData calls +// wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData. +func (c *graphQLMetricsServiceClient) PublishNormalizationCacheWarmupData(ctx context.Context, req *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) { + return c.publishNormalizationCacheWarmupData.CallUnary(ctx, req) +} + // GraphQLMetricsServiceHandler is an implementation of the // wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService service. type GraphQLMetricsServiceHandler interface { // PublishGraphQLMetrics publishes the GraphQL metrics to the metrics service PublishGraphQLMetrics(context.Context, *connect.Request[v1.PublishGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishOperationCoverageReportResponse], error) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) + PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) } // NewGraphQLMetricsServiceHandler builds an HTTP handler from the service implementation. It @@ -128,12 +147,20 @@ func NewGraphQLMetricsServiceHandler(svc GraphQLMetricsServiceHandler, opts ...c connect.WithSchema(graphQLMetricsServicePublishAggregatedGraphQLMetricsMethodDescriptor), connect.WithHandlerOptions(opts...), ) + graphQLMetricsServicePublishNormalizationCacheWarmupDataHandler := connect.NewUnaryHandler( + GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure, + svc.PublishNormalizationCacheWarmupData, + connect.WithSchema(graphQLMetricsServicePublishNormalizationCacheWarmupDataMethodDescriptor), + connect.WithHandlerOptions(opts...), + ) return "/wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case GraphQLMetricsServicePublishGraphQLMetricsProcedure: graphQLMetricsServicePublishGraphQLMetricsHandler.ServeHTTP(w, r) case GraphQLMetricsServicePublishAggregatedGraphQLMetricsProcedure: graphQLMetricsServicePublishAggregatedGraphQLMetricsHandler.ServeHTTP(w, r) + case GraphQLMetricsServicePublishNormalizationCacheWarmupDataProcedure: + graphQLMetricsServicePublishNormalizationCacheWarmupDataHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -150,3 +177,7 @@ func (UnimplementedGraphQLMetricsServiceHandler) PublishGraphQLMetrics(context.C func (UnimplementedGraphQLMetricsServiceHandler) PublishAggregatedGraphQLMetrics(context.Context, *connect.Request[v1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[v1.PublishAggregatedGraphQLRequestMetricsResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishAggregatedGraphQLMetrics is not implemented")) } + +func (UnimplementedGraphQLMetricsServiceHandler) PublishNormalizationCacheWarmupData(context.Context, *connect.Request[v1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[v1.PublishNormalizationCacheWarmupDataResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("wg.cosmo.graphqlmetrics.v1.GraphQLMetricsService.PublishNormalizationCacheWarmupData is not implemented")) +} diff --git a/router/internal/graphqlmetrics/exporter.go b/router/internal/graphqlmetrics/exporter.go index 71a8be9015..78981b3ff2 100644 --- a/router/internal/graphqlmetrics/exporter.go +++ b/router/internal/graphqlmetrics/exporter.go @@ -10,12 +10,13 @@ import ( "github.com/cloudflare/backoff" graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect" + "github.com/wundergraph/cosmo/router/internal/exporter" "go.uber.org/atomic" "go.uber.org/zap" ) type Exporter struct { - settings *ExporterSettings + settings *exporter.Settings logger *zap.Logger client graphqlmetricsv1connect.GraphQLMetricsServiceClient apiToken string @@ -33,55 +34,10 @@ type Exporter struct { cancelAllExportRequests context.CancelFunc } -type RetryOptions struct { - Enabled bool - MaxDuration time.Duration - Interval time.Duration - MaxRetry int -} - -const ( - defaultExportTimeout = time.Duration(10) * time.Second - defaultExportRetryMaxDuration = time.Duration(10) * time.Second - defaultExportRetryInterval = time.Duration(5) * time.Second - defaultExportMaxRetryAttempts = 5 - defaultMaxBatchItems = 1024 - defaultMaxQueueSize = 1024 * 10 - defaultBatchInterval = time.Duration(10) * time.Second -) - -type ExporterSettings struct { - // BatchSize is the maximum number of items to be sent in a single batch. - BatchSize int - // QueueSize is the maximum number of batches allowed in queue at a given time. - QueueSize int - // Interval is the interval at which the queue is flushed. - Interval time.Duration - // Retry is the retry options for the exporter. - RetryOptions RetryOptions - // ExportTimeout is the timeout for the export request. - ExportTimeout time.Duration -} - -func NewDefaultExporterSettings() *ExporterSettings { - return &ExporterSettings{ - BatchSize: defaultMaxBatchItems, - QueueSize: defaultMaxQueueSize, - Interval: defaultBatchInterval, - ExportTimeout: defaultExportTimeout, - RetryOptions: RetryOptions{ - Enabled: true, - MaxRetry: defaultExportMaxRetryAttempts, - MaxDuration: defaultExportRetryMaxDuration, - Interval: defaultExportRetryInterval, - }, - } -} - // NewExporter creates a new GraphQL metrics exporter. The collectorEndpoint is the endpoint to which the metrics // are sent. The apiToken is the token used to authenticate with the collector. The collector supports Brotli compression // and retries on failure. Underling queue implementation sends batches of metrics at the specified interval and batch size. -func NewExporter(logger *zap.Logger, client graphqlmetricsv1connect.GraphQLMetricsServiceClient, apiToken string, settings *ExporterSettings) (*Exporter, error) { +func NewExporter(logger *zap.Logger, client graphqlmetricsv1connect.GraphQLMetricsServiceClient, apiToken string, settings *exporter.Settings) (*Exporter, error) { ctx, cancel := context.WithCancel(context.Background()) e := &Exporter{ logger: logger.With(zap.String("component", "graphqlmetrics_exporter")), diff --git a/router/pkg/config/config.go b/router/pkg/config/config.go index aa1efeac94..1e54c2eb59 100644 --- a/router/pkg/config/config.go +++ b/router/pkg/config/config.go @@ -179,8 +179,20 @@ type SubgraphTrafficRequestRule struct { } type GraphqlMetrics struct { - Enabled bool `yaml:"enabled" envDefault:"true" env:"GRAPHQL_METRICS_ENABLED"` - CollectorEndpoint string `yaml:"collector_endpoint" envDefault:"https://cosmo-metrics.wundergraph.com" env:"GRAPHQL_METRICS_COLLECTOR_ENDPOINT"` + Enabled bool `yaml:"enabled" envDefault:"true" env:"GRAPHQL_METRICS_ENABLED"` + CollectorEndpoint string `yaml:"collector_endpoint" envDefault:"https://cosmo-metrics.wundergraph.com" env:"GRAPHQL_METRICS_COLLECTOR_ENDPOINT"` + BatchInterval time.Duration `yaml:"batch_interval" envDefault:"10s" env:"GRAPHQL_METRICS_BATCH_INTERVAL"` + BatchSize int `yaml:"batch_size" envDefault:"1024" env:"GRAPHQL_METRICS_BATCH_SIZE"` + QueueSize int `yaml:"queue_size" envDefault:"1024" env:"GRAPHQL_METRICS_QUEUE_SIZE"` + ExportTimeout time.Duration `yaml:"export_timeout" envDefault:"10s" env:"GRAPHQL_METRICS_EXPORT_TIMEOUT"` + RetryOptions GraphQLMetricsRetryOptions `yaml:"retry_options"` +} + +type GraphQLMetricsRetryOptions struct { + Enabled bool `yaml:"enabled" envDefault:"true" env:"GRAPHQL_METRICS_RETRY_ENABLED"` + MaxDuration time.Duration `yaml:"max_duration" envDefault:"10s" env:"GRAPHQL_METRICS_RETRY_MAX_DURATION"` + Interval time.Duration `yaml:"interval" envDefault:"5s" env:"GRAPHQL_METRICS_RETRY_INTERVAL"` + MaxAttempts int `yaml:"max_attempts" envDefault:"5" env:"GRAPHQL_METRICS_RETRY_MAX_ATTEMPTS"` } type BackoffJitterRetry struct { diff --git a/router/pkg/config/config.schema.json b/router/pkg/config/config.schema.json index 0219476890..7b64ebeb5f 100644 --- a/router/pkg/config/config.schema.json +++ b/router/pkg/config/config.schema.json @@ -281,6 +281,67 @@ "type": "string", "description": "The endpoint to which the GraphQL metrics are collected. The endpoint is specified as a string with the format 'scheme://host:port'.", "format": "http-url" + }, + "batch_interval": { + "type": "string", + "description": "The interval at which the metrics are collected. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.", + "default": "10s", + "duration": { + "minimum": "1s" + } + }, + "batch_size": { + "type": "integer", + "description": "The size of the batch used to buffer the metrics before sending them to the collector. The default value is 1024.", + "default": 1024, + "minimum": 1 + }, + "queue_size": { + "type": "integer", + "description": "The size of the queue used to buffer the metrics before sending them to the collector. The default value is 1024.", + "default": 1024, + "minimum": 1 + }, + "export_timeout": { + "type": "string", + "description": "The maximum time to wait for the export to complete. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.", + "default": "10s", + "duration": { + "minimum": "1s" + } + }, + "retry_options": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable the retry options. The default value is true.", + "default": true + }, + "max_duration": { + "type": "string", + "description": "The maximum duration to retry the export. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.", + "default": "10s", + "duration": { + "minimum": "1s" + } + }, + "interval": { + "type": "string", + "description": "The interval at which the export is retried. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'.", + "default": "5s", + "duration": { + "minimum": "1s" + } + }, + "max_attempts": { + "type": "integer", + "description": "The maximum number of attempts to retry the export. The default value is 3.", + "default": 5, + "minimum": 1 + } + } } } }, diff --git a/router/pkg/config/testdata/config_defaults.json b/router/pkg/config/testdata/config_defaults.json index 8215fe3cf8..fb1155d262 100644 --- a/router/pkg/config/testdata/config_defaults.json +++ b/router/pkg/config/testdata/config_defaults.json @@ -56,7 +56,17 @@ }, "GraphqlMetrics": { "Enabled": true, - "CollectorEndpoint": "https://cosmo-metrics.wundergraph.com" + "CollectorEndpoint": "https://cosmo-metrics.wundergraph.com", + "BatchInterval": 10000000000, + "BatchSize": 1024, + "QueueSize": 1024, + "ExportTimeout": 10000000000, + "RetryOptions": { + "Enabled": true, + "MaxDuration": 10000000000, + "Interval": 5000000000, + "MaxAttempts": 5 + } }, "CORS": { "Enabled": true, diff --git a/router/pkg/config/testdata/config_full.json b/router/pkg/config/testdata/config_full.json index dc390712d2..b9d1c0ba25 100644 --- a/router/pkg/config/testdata/config_full.json +++ b/router/pkg/config/testdata/config_full.json @@ -75,7 +75,17 @@ }, "GraphqlMetrics": { "Enabled": true, - "CollectorEndpoint": "https://cosmo-metrics.wundergraph.com" + "CollectorEndpoint": "https://cosmo-metrics.wundergraph.com", + "BatchInterval": 10000000000, + "BatchSize": 1024, + "QueueSize": 1024, + "ExportTimeout": 10000000000, + "RetryOptions": { + "Enabled": true, + "MaxDuration": 10000000000, + "Interval": 5000000000, + "MaxAttempts": 5 + } }, "CORS": { "Enabled": true, From 3660f3bec49494231bac542cda51e1054624fe5a Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Fri, 24 Jan 2025 16:55:49 +0100 Subject: [PATCH 4/8] chore: add missing files --- router/internal/exporter/exporter.go | 77 ++++ .../exporter.go | 336 ++++++++++++++++++ 2 files changed, 413 insertions(+) create mode 100644 router/internal/exporter/exporter.go create mode 100644 router/internal/normalizationcachewarmupexporter/exporter.go diff --git a/router/internal/exporter/exporter.go b/router/internal/exporter/exporter.go new file mode 100644 index 0000000000..e0421fa661 --- /dev/null +++ b/router/internal/exporter/exporter.go @@ -0,0 +1,77 @@ +package exporter + +import ( + "time" +) + +type RetryOptions struct { + Enabled bool + MaxDuration time.Duration + Interval time.Duration + MaxRetry int +} + +const ( + defaultExportTimeout = time.Duration(10) * time.Second + defaultExportRetryMaxDuration = time.Duration(10) * time.Second + defaultExportRetryInterval = time.Duration(5) * time.Second + defaultExportMaxRetryAttempts = 5 + defaultMaxBatchItems = 1024 + defaultMaxQueueSize = 1024 * 10 + defaultBatchInterval = time.Duration(10) * time.Second +) + +type Settings struct { + // BatchSize is the maximum number of items to be sent in a single batch. + BatchSize int + // QueueSize is the maximum number of batches allowed in queue at a given time. + QueueSize int + // Interval is the interval at which the queue is flushed. + Interval time.Duration + // Retry is the retry options for the exporter. + RetryOptions RetryOptions + // ExportTimeout is the timeout for the export request. + ExportTimeout time.Duration +} + +func NewDefaultSettings() *Settings { + return &Settings{ + BatchSize: defaultMaxBatchItems, + QueueSize: defaultMaxQueueSize, + Interval: defaultBatchInterval, + ExportTimeout: defaultExportTimeout, + RetryOptions: RetryOptions{ + Enabled: true, + MaxRetry: defaultExportMaxRetryAttempts, + MaxDuration: defaultExportRetryMaxDuration, + Interval: defaultExportRetryInterval, + }, + } +} + +func NewSettings(batchSize, queueSize int, batchInterval, exportTimeout time.Duration, retryEnabled bool, retryMaxAttempts int, retryMaxDuration, retryMaxInterval time.Duration) *Settings { + settings := NewDefaultSettings() + if batchSize > 0 { + settings.BatchSize = batchSize + } + if queueSize > 0 { + settings.QueueSize = queueSize + } + if batchInterval > 0 { + settings.Interval = batchInterval + } + if exportTimeout > 0 { + settings.ExportTimeout = exportTimeout + } + settings.RetryOptions.Enabled = retryEnabled + if retryMaxAttempts > 0 { + settings.RetryOptions.MaxRetry = retryMaxAttempts + } + if retryMaxDuration > 0 { + settings.RetryOptions.MaxDuration = retryMaxDuration + } + if retryMaxInterval > 0 { + settings.RetryOptions.Interval = retryMaxInterval + } + return settings +} diff --git a/router/internal/normalizationcachewarmupexporter/exporter.go b/router/internal/normalizationcachewarmupexporter/exporter.go new file mode 100644 index 0000000000..d271667f86 --- /dev/null +++ b/router/internal/normalizationcachewarmupexporter/exporter.go @@ -0,0 +1,336 @@ +package normalizationcachewarmupexporter + +import ( + "context" + "errors" + "fmt" + "time" + + "connectrpc.com/connect" + "github.com/cloudflare/backoff" + graphqlmetrics "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" + "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect" + "github.com/wundergraph/cosmo/router/internal/exporter" + "go.uber.org/atomic" + "go.uber.org/zap" +) + +type Exporter struct { + settings *exporter.Settings + logger *zap.Logger + client graphqlmetricsv1connect.GraphQLMetricsServiceClient + apiToken string + + shutdownSignal chan struct{} + acceptTrafficSema chan struct{} + + queue chan *graphqlmetrics.NormalizationCacheWarmupData + inflightBatches *atomic.Int64 + + // exportRequestContext is used to cancel all requests that started before the shutdown + exportRequestContext context.Context + // cancelAllExportRequests will be called when we return from the Shutdown func + // this means that we cancel all requests + cancelAllExportRequests context.CancelFunc +} + +// NewExporter creates a new GraphQL metrics exporter. The collectorEndpoint is the endpoint to which the metrics +// are sent. The apiToken is the token used to authenticate with the collector. The collector supports Brotli compression +// and retries on failure. Underling queue implementation sends batches of metrics at the specified interval and batch size. +func NewExporter(logger *zap.Logger, client graphqlmetricsv1connect.GraphQLMetricsServiceClient, apiToken string, settings *exporter.Settings) (*Exporter, error) { + ctx, cancel := context.WithCancel(context.Background()) + e := &Exporter{ + logger: logger.With(zap.String("component", "graphqlmetrics_exporter")), + settings: settings, + client: client, + apiToken: apiToken, + queue: make(chan *graphqlmetrics.NormalizationCacheWarmupData, settings.QueueSize), + shutdownSignal: make(chan struct{}), + acceptTrafficSema: make(chan struct{}), + inflightBatches: atomic.NewInt64(0), + exportRequestContext: ctx, + cancelAllExportRequests: cancel, + } + if err := e.validate(); err != nil { + return nil, err + } + go e.start() + return e, nil +} + +func (e *Exporter) validate() error { + if e.settings.BatchSize <= 0 { + return errors.New("batch size must be positive") + } + + if e.settings.QueueSize <= 0 { + return errors.New("queue size must be positive") + } + + if e.settings.Interval <= 0 { + return errors.New("interval must be positive") + } + + if e.settings.ExportTimeout <= 0 { + return errors.New("export timeout must be positive") + } + + if e.settings.RetryOptions.MaxDuration <= 0 { + return errors.New("retry max duration must be positive") + } + + if e.settings.RetryOptions.Interval <= 0 { + return errors.New("retry interval must be positive") + } + + if e.settings.RetryOptions.MaxRetry <= 0 { + return errors.New("retry max retry must be positive") + } + + return nil +} + +func (e *Exporter) acceptTraffic() bool { + // while the channel is not closed, the select will always return the default case + // once it's closed, the select will always return _,false (closed channel) from the channel + select { + case <-e.acceptTrafficSema: + return false + default: + return true + } +} + +func (e *Exporter) RecordUsage(data *graphqlmetrics.NormalizationCacheWarmupData, synchronous bool) (ok bool) { + if synchronous { + _ = e.send(&graphqlmetrics.NormalizationCacheWarmupDataAggregation{ + Operations: map[uint64]*graphqlmetrics.NormalizationCacheWarmupData{ + data.Query.Hash: data, + }, + }) + return true + } + if !e.acceptTraffic() { + return false + } + select { + case e.queue <- data: + return true + default: + e.logger.Warn("RecordAsync: Queue is full, dropping item") + return false + } +} + +func (e *Exporter) send(aggregation *graphqlmetrics.NormalizationCacheWarmupDataAggregation) error { + e.logger.Debug("sending item") + ctx := e.exportRequestContext + if e.settings.ExportTimeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(e.exportRequestContext, e.settings.ExportTimeout) + defer cancel() + } + + req := connect.NewRequest(&graphqlmetrics.PublishNormalizationCacheWarmupDataRequest{ + Aggregation: aggregation, + }) + + req.Header().Set("Authorization", fmt.Sprintf("Bearer %s", e.apiToken)) + + _, err := e.client.PublishNormalizationCacheWarmupData(ctx, req) + if err != nil { + e.logger.Debug("Failed to export batch", zap.Error(err)) + return err + } + + e.logger.Debug("Successfully exported batch") + + return nil +} + +func (e *Exporter) prepareAndSendBatch(batch []*graphqlmetrics.NormalizationCacheWarmupData) { + e.logger.Debug("Exporter.prepareAndSendBatch", zap.Int("batch_size", len(batch))) + e.inflightBatches.Inc() + go func() { + defer e.inflightBatches.Dec() + e.aggregateAndSendBatch(batch) + }() +} + +// export sends the batch to the configured endpoint. +func (e *Exporter) aggregateAndSendBatch(batch []*graphqlmetrics.NormalizationCacheWarmupData) { + b := backoff.New(e.settings.RetryOptions.MaxDuration, e.settings.RetryOptions.Interval) + defer b.Reset() + + request := e.aggregate(batch) + + err := e.send(request) + if err == nil { + return + } + + var connectErr *connect.Error + if errors.As(err, &connectErr) && connectErr.Code() == connect.CodeUnauthenticated { + e.logger.Error("Failed to export batch due to unauthenticated error, not retrying", + zap.Error(err), + zap.Int("batch_size", len(request.Operations)), + ) + return + } + + if !e.settings.RetryOptions.Enabled { + e.logger.Error("Failed to export batch", + zap.Error(err), + zap.Int("batch_size", len(request.Operations)), + ) + return + } + + var retry int + var lastErr error + + for retry <= e.settings.RetryOptions.MaxRetry { + + retry++ + + // Wait for the specified backoff period + sleepDuration := b.Duration() + + e.logger.Debug(fmt.Sprintf("Retrying export in %s ...", sleepDuration.String()), + zap.Int("batch_size", len(request.Operations)), + zap.Int("retry", retry), + zap.Duration("sleep", sleepDuration), + ) + + // Wait for the specified backoff period + time.Sleep(sleepDuration) + + err = e.send(request) + if err == nil { + return + } + if errors.As(err, &connectErr) && connectErr.Code() == connect.CodeUnauthenticated { + e.logger.Error("Failed to export batch due to unauthenticated error, not retrying", + zap.Error(err), + zap.Int("batch_size", len(request.Operations)), + ) + return + } + lastErr = err + } + + e.logger.Error("Failed to export batch after retries", + zap.Error(lastErr), + zap.Int("batch_size", len(request.Operations)), + zap.Int("retries", retry), + ) +} + +func (e *Exporter) aggregate(batch []*graphqlmetrics.NormalizationCacheWarmupData) *graphqlmetrics.NormalizationCacheWarmupDataAggregation { + aggregation := &graphqlmetrics.NormalizationCacheWarmupDataAggregation{ + Operations: make(map[uint64]*graphqlmetrics.NormalizationCacheWarmupData), + } + + for _, item := range batch { + if existing, ok := aggregation.Operations[item.Query.Hash]; ok { + for k, v := range item.VariableVariations { + existing.VariableVariations[k] = v + } + } else { + aggregation.Operations[item.Query.Hash] = item + } + } + + return aggregation +} + +// start starts the exporter and blocks until the exporter is shutdown. +func (e *Exporter) start() { + e.logger.Debug("Starting exporter") + ticker := time.NewTicker(e.settings.Interval) + defer func() { + ticker.Stop() + e.logger.Debug("Exporter stopped") + }() + + var buffer []*graphqlmetrics.NormalizationCacheWarmupData + + for { + if buffer == nil { + buffer = make([]*graphqlmetrics.NormalizationCacheWarmupData, 0, e.settings.BatchSize) + } + select { + case <-ticker.C: + e.logger.Debug("Exporter.start: tick") + if len(buffer) > 0 { + e.prepareAndSendBatch(buffer) + buffer = nil + } + case item := <-e.queue: + e.logger.Debug("Exporter.start: item") + buffer = append(buffer, item) + if len(buffer) == e.settings.BatchSize { + e.prepareAndSendBatch(buffer) + buffer = nil + } + case <-e.shutdownSignal: + e.logger.Debug("Exporter.start: shutdown") + e.drainQueue(buffer) + return + } + } +} + +func (e *Exporter) drainQueue(buffer []*graphqlmetrics.NormalizationCacheWarmupData) { + e.logger.Debug("Exporter.closeAndDrainQueue") + drainedItems := 0 + for { + select { + case item := <-e.queue: + drainedItems++ + buffer = append(buffer, item) + if len(buffer) == e.settings.BatchSize { + e.prepareAndSendBatch(buffer) + buffer = make([]*graphqlmetrics.NormalizationCacheWarmupData, 0, e.settings.BatchSize) + } + default: + if len(buffer) > 0 { + e.prepareAndSendBatch(buffer) + } + e.logger.Debug("Exporter.closeAndDrainQueue: done", zap.Int("drained_items", drainedItems)) + return + } + } +} + +// Shutdown the exporter but waits until all export jobs has been finished or timeout. +// If the context is canceled, the exporter will be shutdown immediately. +func (e *Exporter) Shutdown(ctx context.Context) error { + ticker := time.NewTicker(time.Millisecond * 100) + defer func() { + ticker.Stop() + // cancel all requests + e.cancelAllExportRequests() + e.logger.Debug("Exporter.Shutdown: done") + }() + + // first close the acceptTrafficSema to stop accepting new items + close(e.acceptTrafficSema) + // then trigger the shutdown signal for the exporter goroutine to stop + // it will then drain the queue and send the remaining items + close(e.shutdownSignal) + + // we're polling the inflightBatches to wait for all inflight batches to finish or timeout + // we're not using a wait group here because you can't wait for a wait group with a timeout + + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + if e.inflightBatches.Load() == 0 { + return nil + } + } + } +} From 6d165697082c81a1543c5c62c3498a2579d85fb9 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Fri, 24 Jan 2025 17:28:08 +0100 Subject: [PATCH 5/8] chore: merge main --- router-tests/cache_warmup_test.go | 28 ++++---- router-tests/testenv/testenv.go | 10 +-- router/core/cache_warmup.go | 69 ++++++++++++------- router/core/router.go | 10 +-- .../internal/graphqlmetrics/exporter_test.go | 30 +++++--- 5 files changed, 81 insertions(+), 66 deletions(-) diff --git a/router-tests/cache_warmup_test.go b/router-tests/cache_warmup_test.go index afff34f89e..5998253941 100644 --- a/router-tests/cache_warmup_test.go +++ b/router-tests/cache_warmup_test.go @@ -2,19 +2,19 @@ package integration import ( "context" + "net/http" + "os" + "testing" + "time" + nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "github.com/wundergraph/cosmo/router/pkg/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" "go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest" - "net/http" - "os" - "testing" - "time" "github.com/stretchr/testify/require" - nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "go.uber.org/zap" "google.golang.org/protobuf/encoding/protojson" @@ -945,14 +945,16 @@ func TestCacheWarmupMetrics(t *testing.T) { ModifyRouterConfig: func(routerConfig *nodev1.RouterConfig) { routerConfig.FeatureFlagConfigs = nil }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 1, - QueryNormalizationHits: 2, - ValidationMisses: 1, - ValidationHits: 2, - PlanMisses: 1, - PlanHits: 2, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 1, + QueryNormalizationHits: 2, + ValidationMisses: 1, + ValidationHits: 2, + PlanMisses: 1, + PlanHits: 2, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { diff --git a/router-tests/testenv/testenv.go b/router-tests/testenv/testenv.go index a8cc1d2fc8..ce452336ce 100644 --- a/router-tests/testenv/testenv.go +++ b/router-tests/testenv/testenv.go @@ -6,6 +6,7 @@ import ( "context" "crypto/tls" "crypto/x509" + _ "embed" "encoding/json" "errors" "fmt" @@ -35,13 +36,6 @@ import ( "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-retryablehttp" "github.com/nats-io/nats.go" - "github.com/hashicorp/consul/sdk/freeport" - - "github.com/wundergraph/cosmo/router/pkg/logging" - - "go.uber.org/zap/zaptest/observer" - - "github.com/wundergraph/cosmo/router/pkg/controlplane/configpoller" "github.com/nats-io/nats.go/jetstream" "github.com/prometheus/client_golang/prometheus" @@ -66,8 +60,6 @@ import ( rmetric "github.com/wundergraph/cosmo/router/pkg/metric" pubsubNats "github.com/wundergraph/cosmo/router/pkg/pubsub/nats" "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/datasource/pubsub_datasource" - - _ "embed" ) var ErrEnvironmentClosed = errors.New("test environment closed") diff --git a/router/core/cache_warmup.go b/router/core/cache_warmup.go index 249d0f0d09..103b86cfa1 100644 --- a/router/core/cache_warmup.go +++ b/router/core/cache_warmup.go @@ -246,21 +246,29 @@ func (c *CacheWarmupPlanningProcessor) ProcessOperation(ctx context.Context, ope request := operation.GetRequest() client := operation.GetClient() variations := request.GetVariableVariations() + result := &CacheWarmupOperationPlanResult{ + ClientName: client.Name, + ClientVersion: client.Version, + } if len(variations) == 0 { - return c.processOperation(ctx, request, client) + err := c.processOperation(ctx, request, result, client) + if err != nil { + return nil, err + } + return result, nil } for _, variation := range variations { variables := variation.GetVariables() request.Variables = variables - res,err := c.processOperation(ctx, request, client) + err := c.processOperation(ctx, request, result, client) if err != nil { - return err + return nil, err } } - return nil + return result, nil } -func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, request *nodev1.OperationRequest, client *nodev1.ClientInfo) (*CacheWarmupOperationPlanResult, error) { +func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, request *nodev1.OperationRequest, result *CacheWarmupOperationPlanResult, client *nodev1.ClientInfo) error { var ( isAPQ bool @@ -268,14 +276,14 @@ func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, req k, err := c.operationProcessor.NewIndependentKit() if err != nil { - return nil, err + return err } var s []byte if request.GetExtensions() != nil { s, err = protojson.Marshal(request.GetExtensions()) if err != nil { - return nil, err + return err } } @@ -302,44 +310,44 @@ func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, req err = k.unmarshalOperation() if err != nil { - return nil, err + return err } err = k.ComputeOperationSha256() if err != nil { - return nil, err + return err } if k.parsedOperation.IsPersistedOperation { _, isAPQ, err = k.FetchPersistedOperation(ctx, item.Client) if err != nil { - return nil, err + return err } } err = k.Parse() if err != nil { - return nil, err + return err } _, err = k.NormalizeOperation(item.Client.Name, isAPQ) if err != nil { - return nil, err + return err } err = k.NormalizeVariables() if err != nil { - return nil, err + return err } err = k.RemapVariables() if err != nil { - return nil, err + return err } _, err = k.Validate(true, k.parsedOperation.RemapVariables) if err != nil { - return nil, err + return err } if c.complexityLimits != nil { @@ -370,22 +378,31 @@ func (c *CacheWarmupPlanningProcessor) processOperation(ctx context.Context, req opContext.variables, err = astjson.ParseBytes(k.parsedOperation.Request.Variables) if err != nil { - return nil, err + return err } - planningStart := time.Now() + start := time.Now() err = c.operationPlanner.plan(opContext, planOptions) if err != nil { - return nil, err + return err + } + + if result.PlanningTime == 0 { + result.PlanningTime = time.Since(start) } - return &CacheWarmupOperationPlanResult{ - OperationHash: strconv.FormatUint(k.parsedOperation.ID, 10), - OperationName: k.parsedOperation.Request.OperationName, - OperationType: k.parsedOperation.Type, - ClientName: item.Client.Name, - ClientVersion: item.Client.Version, - PlanningTime: time.Since(planningStart), - }, nil + if result.OperationHash == "" { + result.OperationHash = strconv.FormatUint(k.parsedOperation.ID, 10) + } + + if result.OperationName == "" { + result.OperationName = k.parsedOperation.Request.OperationName + } + + if result.OperationType == "" { + result.OperationType = k.parsedOperation.Type + } + + return nil } diff --git a/router/core/router.go b/router/core/router.go index 3524f70719..9bda302068 100644 --- a/router/core/router.go +++ b/router/core/router.go @@ -28,9 +28,7 @@ import ( "github.com/mitchellh/mapstructure" "github.com/nats-io/nuid" "github.com/redis/go-redis/v9" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/propagation" sdkmetric "go.opentelemetry.io/otel/sdk/metric" sdktrace "go.opentelemetry.io/otel/sdk/trace" "go.uber.org/atomic" @@ -43,9 +41,6 @@ import ( "github.com/wundergraph/cosmo/router/internal/graphiql" "github.com/wundergraph/cosmo/router/internal/graphqlmetrics" "github.com/wundergraph/cosmo/router/internal/persistedoperation" - "github.com/wundergraph/cosmo/router/internal/persistedoperation/apq" - "github.com/wundergraph/cosmo/router/internal/persistedoperation/operationstorage/cdn" - "github.com/wundergraph/cosmo/router/internal/persistedoperation/operationstorage/s3" "github.com/wundergraph/cosmo/router/internal/retrytransport" "github.com/wundergraph/cosmo/router/internal/stringsx" "github.com/wundergraph/cosmo/router/pkg/config" @@ -59,7 +54,6 @@ import ( "github.com/wundergraph/cosmo/router/pkg/statistics" rtrace "github.com/wundergraph/cosmo/router/pkg/trace" "github.com/wundergraph/cosmo/router/pkg/watcher" - "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" ) type IPAnonymizationMethod string @@ -195,7 +189,7 @@ type ( healthCheckPath string readinessCheckPath string livenessCheckPath string - playgroundConfig config.PlaygroundConfig + playgroundConfig config.PlaygroundConfig cacheControlPolicy config.CacheControlPolicy routerConfigPollerConfig *RouterConfigPollerConfig cdnConfig config.CDNConfiguration @@ -1745,7 +1739,7 @@ func DefaultGraphQLMetricsConfig() *GraphQLMetricsConfig { }{ Enabled: true, MaxDuration: time.Second * 5, - Interval: time.Second, *5, + Interval: time.Second * 5, MaxAttempts: 5, }, } diff --git a/router/internal/graphqlmetrics/exporter_test.go b/router/internal/graphqlmetrics/exporter_test.go index a5c521e4f3..5c62388698 100644 --- a/router/internal/graphqlmetrics/exporter_test.go +++ b/router/internal/graphqlmetrics/exporter_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" graphqlmetricsv1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetricsv1connect" + "github.com/wundergraph/cosmo/router/internal/exporter" "go.uber.org/zap" ) @@ -19,9 +20,18 @@ type MyClient struct { t *testing.T publishedBatches [][]*graphqlmetricsv1.SchemaUsageInfo publishedAggregations [][]*graphqlmetricsv1.SchemaUsageInfoAggregation + publishedWarmups []*graphqlmetricsv1.NormalizationCacheWarmupDataAggregation mu sync.Mutex } +func (m *MyClient) PublishNormalizationCacheWarmupData(ctx context.Context, c *connect.Request[graphqlmetricsv1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[graphqlmetricsv1.PublishNormalizationCacheWarmupDataResponse], error) { + m.mu.Lock() + defer m.mu.Unlock() + require.Equal(m.t, "Bearer secret", c.Header().Get("Authorization")) + m.publishedWarmups = append(m.publishedWarmups, c.Msg.Aggregation) + return nil, nil +} + func (m *MyClient) PublishAggregatedGraphQLMetrics(ctx context.Context, c *connect.Request[graphqlmetricsv1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[graphqlmetricsv1.PublishAggregatedGraphQLRequestMetricsResponse], error) { m.mu.Lock() defer m.mu.Unlock() @@ -53,11 +63,11 @@ func TestExportAggregationSameSchemaUsages(t *testing.T) { zap.NewNop(), c, "secret", - &ExporterSettings{ + &exporter.Settings{ BatchSize: batchSize, QueueSize: queueSize, Interval: 500 * time.Millisecond, - RetryOptions: RetryOptions{ + RetryOptions: exporter.RetryOptions{ Enabled: false, MaxDuration: 300 * time.Millisecond, Interval: 100 * time.Millisecond, @@ -132,11 +142,11 @@ func TestExportBatchesWithUniqueSchemaUsages(t *testing.T) { zap.NewNop(), c, "secret", - &ExporterSettings{ + &exporter.Settings{ BatchSize: batchSize, QueueSize: queueSize, Interval: time.Second * 5, - RetryOptions: RetryOptions{ + RetryOptions: exporter.RetryOptions{ Enabled: false, MaxDuration: 300 * time.Millisecond, Interval: 100 * time.Millisecond, @@ -201,13 +211,13 @@ func TestForceFlushSync(t *testing.T) { zap.NewNop(), c, "secret", - &ExporterSettings{ + &exporter.Settings{ BatchSize: batchSize, QueueSize: queueSize, // Intentionally set to a high value to make sure that the exporter is forced to flush immediately Interval: 5000 * time.Millisecond, ExportTimeout: 5000 * time.Millisecond, - RetryOptions: RetryOptions{ + RetryOptions: exporter.RetryOptions{ Enabled: false, MaxDuration: 300 * time.Millisecond, Interval: 100 * time.Millisecond, @@ -316,11 +326,11 @@ func TestExportBatchInterval(t *testing.T) { zap.NewNop(), c, "secret", - &ExporterSettings{ + &exporter.Settings{ BatchSize: batchSize, QueueSize: queueSize, Interval: 100 * time.Millisecond, - RetryOptions: RetryOptions{ + RetryOptions: exporter.RetryOptions{ Enabled: false, MaxDuration: 300 * time.Millisecond, Interval: 100 * time.Millisecond, @@ -388,11 +398,11 @@ func TestExportFullQueue(t *testing.T) { zap.NewNop(), c, "secret", - &ExporterSettings{ + &exporter.Settings{ BatchSize: batchSize, QueueSize: queueSize, Interval: 500 * time.Millisecond, - RetryOptions: RetryOptions{ + RetryOptions: exporter.RetryOptions{ Enabled: false, MaxDuration: 300 * time.Millisecond, Interval: 100 * time.Millisecond, From 5aa183594855dba117ea463dff370ef89b906d9f Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Sat, 25 Jan 2025 20:44:07 +0100 Subject: [PATCH 6/8] chore: add test to exporter --- .../exporter_test.go | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 router/internal/normalizationcachewarmupexporter/exporter_test.go diff --git a/router/internal/normalizationcachewarmupexporter/exporter_test.go b/router/internal/normalizationcachewarmupexporter/exporter_test.go new file mode 100644 index 0000000000..89633c0a7f --- /dev/null +++ b/router/internal/normalizationcachewarmupexporter/exporter_test.go @@ -0,0 +1,185 @@ +package normalizationcachewarmupexporter + +import ( + "context" + "sync" + "testing" + "time" + + "connectrpc.com/connect" + "github.com/cespare/xxhash/v2" + "github.com/stretchr/testify/require" + "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/graphqlmetrics/v1" + "github.com/wundergraph/cosmo/router/internal/exporter" + "go.uber.org/zap" +) + +type FakeClient struct { + wg sync.WaitGroup + mu sync.Mutex + aggregations []*graphqlmetricsv1.NormalizationCacheWarmupDataAggregation +} + +func (f *FakeClient) PublishGraphQLMetrics(ctx context.Context, c *connect.Request[graphqlmetricsv1.PublishGraphQLRequestMetricsRequest]) (*connect.Response[graphqlmetricsv1.PublishOperationCoverageReportResponse], error) { + return nil, nil +} + +func (f *FakeClient) PublishAggregatedGraphQLMetrics(ctx context.Context, c *connect.Request[graphqlmetricsv1.PublishAggregatedGraphQLRequestMetricsRequest]) (*connect.Response[graphqlmetricsv1.PublishAggregatedGraphQLRequestMetricsResponse], error) { + return nil, nil +} + +func (f *FakeClient) PublishNormalizationCacheWarmupData(ctx context.Context, c *connect.Request[graphqlmetricsv1.PublishNormalizationCacheWarmupDataRequest]) (*connect.Response[graphqlmetricsv1.PublishNormalizationCacheWarmupDataResponse], error) { + f.mu.Lock() + defer f.mu.Unlock() + defer f.wg.Done() + f.aggregations = append(f.aggregations, c.Msg.Aggregation) + return &connect.Response[graphqlmetricsv1.PublishNormalizationCacheWarmupDataResponse]{ + Msg: &graphqlmetricsv1.PublishNormalizationCacheWarmupDataResponse{}, + }, nil +} + +func TestExporter(t *testing.T) { + + c := &FakeClient{} + + e, err := NewExporter( + zap.NewNop(), + c, + "secret", + &exporter.Settings{ + BatchSize: 2, + QueueSize: 2, + Interval: 500 * time.Millisecond, + RetryOptions: exporter.RetryOptions{ + Enabled: false, + MaxDuration: 300 * time.Millisecond, + Interval: 100 * time.Millisecond, + MaxRetry: 3, + }, + ExportTimeout: 100 * time.Millisecond, + }, + ) + require.NoError(t, err) + + t.Cleanup(func() { + _ = e.Shutdown(context.Background()) + }) + + c.wg.Add(1) + + ok := e.RecordUsage(&graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: "query { field }", + Hash: xxhash.Sum64([]byte("query { field }")), + }, + }, false) + require.True(t, ok) + + ok = e.RecordUsage(&graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: "query { field }", + Hash: xxhash.Sum64([]byte("query { field }")), + }, + }, false) + require.True(t, ok) + + c.wg.Wait() + + c.mu.Lock() + defer c.mu.Unlock() + + require.Len(t, c.aggregations, 1) + require.Len(t, c.aggregations[0].Operations, 1) +} + +func TestExporterWithVariables(t *testing.T) { + + c := &FakeClient{} + + e, err := NewExporter( + zap.NewNop(), + c, + "secret", + &exporter.Settings{ + BatchSize: 3, + QueueSize: 3, + Interval: 500 * time.Millisecond, + RetryOptions: exporter.RetryOptions{ + Enabled: false, + MaxDuration: 300 * time.Millisecond, + Interval: 100 * time.Millisecond, + MaxRetry: 3, + }, + ExportTimeout: 100 * time.Millisecond, + }, + ) + require.NoError(t, err) + + t.Cleanup(func() { + _ = e.Shutdown(context.Background()) + }) + + c.wg.Add(1) + + ok := e.RecordUsage(&graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: "query { otherField }", + Hash: xxhash.Sum64([]byte("query { otherField }")), + }, + }, false) + require.True(t, ok) + + ok = e.RecordUsage(&graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: "query { field }", + Hash: xxhash.Sum64([]byte("query { field }")), + }, + VariableVariations: map[uint64]*graphqlmetricsv1.VariableVariation{ + 0: { + VariableValues: []*graphqlmetricsv1.VariableValue{ + { + Key: "a", + Value: true, + }, + }, + }, + }, + }, false) + require.True(t, ok) + + ok = e.RecordUsage(&graphqlmetricsv1.NormalizationCacheWarmupData{ + Query: &graphqlmetricsv1.NormalizationCacheWarmupDataQuery{ + Query: "query { field }", + Hash: xxhash.Sum64([]byte("query { field }")), + }, + VariableVariations: map[uint64]*graphqlmetricsv1.VariableVariation{ + 0: { + VariableValues: []*graphqlmetricsv1.VariableValue{ + { + Key: "a", + Value: true, + }, + }, + }, + 1: { + VariableValues: []*graphqlmetricsv1.VariableValue{ + { + Key: "b", + Value: true, + }, + }, + }, + }, + }, false) + require.True(t, ok) + + c.wg.Wait() + + c.mu.Lock() + defer c.mu.Unlock() + + require.Len(t, c.aggregations, 1) + require.Len(t, c.aggregations[0].Operations, 2) + require.Len(t, c.aggregations[0].Operations[xxhash.Sum64([]byte("query { otherField }"))].VariableVariations, 0) + require.Len(t, c.aggregations[0].Operations[xxhash.Sum64([]byte("query { field }"))].VariableVariations, 2) +} From 68af81d29c0bafec1bca23a7fb736f19f5c255f8 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Sat, 25 Jan 2025 20:44:15 +0100 Subject: [PATCH 7/8] chore: add comments on proto --- proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto index d327513024..7398715660 100644 --- a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto +++ b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto @@ -125,7 +125,9 @@ message NormalizationCacheWarmupData { } message NormalizationCacheWarmupDataQuery { + // Query is the original query sent by the client string Query = 1; + // Hash is the hash of the fully normalized query uint64 Hash = 2; } From 54fd0158ac9e7f90f85077eb609602cd7e68e9ec Mon Sep 17 00:00:00 2001 From: StarpTech Date: Sat, 8 Feb 2025 22:38:53 +0100 Subject: [PATCH 8/8] chore: merge --- .../gen/proto/wg/cosmo/node/v1/node.pb.go | 325 ++++++++++++------ connect/src/wg/cosmo/node/v1/node_pb.ts | 53 +++ .../graphqlmetrics/v1/graphqlmetrics.pb.go | 4 +- router-tests/cache_warmup_test.go | 22 +- router-tests/ratelimit_test.go | 10 +- router/core/router.go | 7 + .../graphqlmetrics/v1/graphqlmetrics.pb.go | 4 +- router/gen/proto/wg/cosmo/node/v1/node.pb.go | 325 ++++++++++++------ 8 files changed, 515 insertions(+), 235 deletions(-) diff --git a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go index c343294f6d..a5e87f018c 100644 --- a/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/connect-go/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3127,6 +3127,11 @@ type OperationRequest struct { OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + // we're only interested in variables that are relevant for normalization + // as such, we only need booleans that are used for skip/include + // consequently, variables is a map of key->bool + Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } func (x *OperationRequest) Reset() { @@ -3182,6 +3187,67 @@ func (x *OperationRequest) GetExtensions() *Extension { return nil } +func (x *OperationRequest) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + +func (x *OperationRequest) GetVariableVariations() []*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Variables map[string]bool `protobuf:"bytes,1,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} +} + +func (x *VariableVariation) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + type Extension struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3193,7 +3259,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3206,7 +3272,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3219,7 +3285,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -3241,7 +3307,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3254,7 +3320,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3267,7 +3333,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *PersistedQuery) GetSha256Hash() string { @@ -3296,7 +3362,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3309,7 +3375,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3322,7 +3388,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *ClientInfo) GetName() string { @@ -3912,7 +3978,7 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0xf1, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, @@ -3921,73 +3987,98 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x3b, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x09, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x22, 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, - 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, - 0x0a, 0x1b, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, - 0x17, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, - 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, - 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, - 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, - 0x10, 0x02, 0x2a, 0x36, 0x0a, 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, - 0x49, 0x45, 0x4c, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, - 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, - 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, - 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, - 0x48, 0x51, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, - 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, - 0x0a, 0x07, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, - 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, - 0x43, 0x52, 0x49, 0x42, 0x45, 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, - 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, - 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, - 0x45, 0x48, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, - 0x2a, 0x41, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, - 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, - 0x01, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, - 0x53, 0x10, 0x04, 0x32, 0x6e, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x12, 0x25, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, - 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0xcf, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, - 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2d, - 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, - 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, - 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x1c, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, - 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x13, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, - 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x09, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x54, 0x0a, + 0x13, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x12, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xa3, 0x01, 0x0a, 0x11, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x08, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, + 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, + 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, + 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, + 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, + 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, + 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, + 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, + 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, + 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, + 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, + 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, + 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, + 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, + 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, + 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, + 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, + 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, + 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, + 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcf, + 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, + 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, + 0x02, 0x03, 0x57, 0x43, 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, + 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, + 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4003,7 +4094,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 51) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 54) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -4056,31 +4147,34 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*CacheWarmerOperations)(nil), // 48: wg.cosmo.node.v1.CacheWarmerOperations (*Operation)(nil), // 49: wg.cosmo.node.v1.Operation (*OperationRequest)(nil), // 50: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 51: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 52: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 53: wg.cosmo.node.v1.ClientInfo - nil, // 54: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 55: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 56: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 57: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 58: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 59: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*VariableVariation)(nil), // 51: wg.cosmo.node.v1.VariableVariation + (*Extension)(nil), // 52: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 53: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 54: wg.cosmo.node.v1.ClientInfo + nil, // 55: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 56: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 57: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + nil, // 58: wg.cosmo.node.v1.OperationRequest.VariablesEntry + nil, // 59: wg.cosmo.node.v1.VariableVariation.VariablesEntry + (common.EnumStatusCode)(0), // 60: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 61: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 62: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 54, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 55, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 16, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 16, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 7, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 57, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 60, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 13, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 10, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 12, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 17, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration 21, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration 22, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 55, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 56, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind 23, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField 23, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField @@ -4102,7 +4196,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 25, // 32: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition 37, // 33: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable 5, // 34: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 56, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 57, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry 37, // 36: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable 39, // 37: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration 41, // 38: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration @@ -4126,26 +4220,29 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 37, // 56: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 57: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 58: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 59, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 61, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 62, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol 47, // 61: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 46, // 62: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition 47, // 63: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 47, // 64: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 49, // 65: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation 50, // 66: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 53, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 51, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 52, // 69: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 8, // 70: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 40, // 71: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 14, // 72: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 15, // 73: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 73, // [73:74] is the sub-list for method output_type - 72, // [72:73] is the sub-list for method input_type - 72, // [72:72] is the sub-list for extension type_name - 72, // [72:72] is the sub-list for extension extendee - 0, // [0:72] is the sub-list for field type_name + 54, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 52, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 58, // 69: wg.cosmo.node.v1.OperationRequest.variables:type_name -> wg.cosmo.node.v1.OperationRequest.VariablesEntry + 51, // 70: wg.cosmo.node.v1.OperationRequest.variable_variations:type_name -> wg.cosmo.node.v1.VariableVariation + 59, // 71: wg.cosmo.node.v1.VariableVariation.variables:type_name -> wg.cosmo.node.v1.VariableVariation.VariablesEntry + 53, // 72: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 8, // 73: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 40, // 74: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 14, // 75: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 15, // 76: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 76, // [76:77] is the sub-list for method output_type + 75, // [75:76] is the sub-list for method input_type + 75, // [75:75] is the sub-list for extension type_name + 75, // [75:75] is the sub-list for extension extendee + 0, // [0:75] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -4695,7 +4792,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*Extension); i { + switch v := v.(*VariableVariation); i { case 0: return &v.state case 1: @@ -4707,7 +4804,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*PersistedQuery); i { + switch v := v.(*Extension); i { case 0: return &v.state case 1: @@ -4719,6 +4816,18 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*PersistedQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_node_v1_node_proto_msgTypes[48].Exporter = func(v any, i int) any { switch v := v.(*ClientInfo); i { case 0: return &v.state @@ -4745,7 +4854,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_node_v1_node_proto_rawDesc, NumEnums: 6, - NumMessages: 51, + NumMessages: 54, NumExtensions: 0, NumServices: 1, }, diff --git a/connect/src/wg/cosmo/node/v1/node_pb.ts b/connect/src/wg/cosmo/node/v1/node_pb.ts index 7125c77c80..a145d630ce 100644 --- a/connect/src/wg/cosmo/node/v1/node_pb.ts +++ b/connect/src/wg/cosmo/node/v1/node_pb.ts @@ -2377,6 +2377,20 @@ export class OperationRequest extends Message { */ extensions?: Extension; + /** + * we're only interested in variables that are relevant for normalization + * as such, we only need booleans that are used for skip/include + * consequently, variables is a map of key->bool + * + * @generated from field: map variables = 4; + */ + variables: { [key: string]: boolean } = {}; + + /** + * @generated from field: repeated wg.cosmo.node.v1.VariableVariation variable_variations = 5; + */ + variableVariations: VariableVariation[] = []; + constructor(data?: PartialMessage) { super(); proto3.util.initPartial(data, this); @@ -2388,6 +2402,8 @@ export class OperationRequest extends Message { { no: 1, name: "operation_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 2, name: "query", kind: "scalar", T: 9 /* ScalarType.STRING */ }, { no: 3, name: "extensions", kind: "message", T: Extension }, + { no: 4, name: "variables", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "scalar", T: 8 /* ScalarType.BOOL */} }, + { no: 5, name: "variable_variations", kind: "message", T: VariableVariation, repeated: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): OperationRequest { @@ -2407,6 +2423,43 @@ export class OperationRequest extends Message { } } +/** + * @generated from message wg.cosmo.node.v1.VariableVariation + */ +export class VariableVariation extends Message { + /** + * @generated from field: map variables = 1; + */ + variables: { [key: string]: boolean } = {}; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "wg.cosmo.node.v1.VariableVariation"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "variables", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "scalar", T: 8 /* ScalarType.BOOL */} }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): VariableVariation { + return new VariableVariation().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): VariableVariation { + return new VariableVariation().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): VariableVariation { + return new VariableVariation().fromJsonString(jsonString, options); + } + + static equals(a: VariableVariation | PlainMessage | undefined, b: VariableVariation | PlainMessage | undefined): boolean { + return proto3.util.equals(VariableVariation, a, b); + } +} + /** * @generated from message wg.cosmo.node.v1.Extension */ diff --git a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index 9d73c3c9c7..87315dad5a 100644 --- a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -963,8 +963,10 @@ type NormalizationCacheWarmupDataQuery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Query is the original query sent by the client Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` - Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` + // Hash is the hash of the fully normalized query + Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` } func (x *NormalizationCacheWarmupDataQuery) Reset() { diff --git a/router-tests/cache_warmup_test.go b/router-tests/cache_warmup_test.go index 2f69d5cd14..bcc6108c69 100644 --- a/router-tests/cache_warmup_test.go +++ b/router-tests/cache_warmup_test.go @@ -9,10 +9,6 @@ import ( nodev1 "github.com/wundergraph/cosmo/router/gen/proto/wg/cosmo/node/v1" "github.com/wundergraph/cosmo/router/pkg/otel" - "net/http" - "testing" - "time" - "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/metricdata" @@ -136,14 +132,16 @@ func TestCacheWarmup(t *testing.T) { }, }), }, - AssertCacheMetrics: &testenv.CacheMetricsAssertions{ - BaseGraphAssertions: testenv.CacheMetricsAssertion{ - QueryNormalizationMisses: 3 + employeeWarmedQueryCount + employeeQueryCount, - QueryNormalizationHits: 4, - ValidationMisses: 5 + employeeWarmedQueryCount, - ValidationHits: 2 + employeeQueryCount, - PlanMisses: 5 + employeeWarmedQueryCount, - PlanHits: 2 + employeeQueryCount, + AssertCacheMetrics: &testenv.AssertCacheMetrics{ + After: &testenv.CacheMetricsAssertions{ + BaseGraphAssertions: testenv.CacheMetricsAssertion{ + QueryNormalizationMisses: 3 + employeeWarmedQueryCount + employeeQueryCount, + QueryNormalizationHits: 4, + ValidationMisses: 5 + employeeWarmedQueryCount, + ValidationHits: 2 + employeeQueryCount, + PlanMisses: 5 + employeeWarmedQueryCount, + PlanHits: 2 + employeeQueryCount, + }, }, }, }, func(t *testing.T, xEnv *testenv.Environment) { diff --git a/router-tests/ratelimit_test.go b/router-tests/ratelimit_test.go index b0176f7fbd..f0a47e3862 100644 --- a/router-tests/ratelimit_test.go +++ b/router-tests/ratelimit_test.go @@ -723,7 +723,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ ClusterEnabled: true, URLs: tt.clusterUrlSlice, KeyPrefix: key, @@ -762,7 +762,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ ClusterEnabled: true, URLs: clusterUrlSlice, KeyPrefix: key, @@ -795,7 +795,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ ClusterEnabled: true, URLs: clusterUrlSlice, KeyPrefix: key, @@ -831,7 +831,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ ClusterEnabled: true, URLs: clusterUrlSlice, KeyPrefix: key, @@ -871,7 +871,7 @@ func TestRateLimit(t *testing.T) { Period: time.Second * 2, RejectExceedingRequests: false, }, - Storage: config.RedisConfiguration{ + Storage: config.RateLimitRedisConfiguration{ ClusterEnabled: true, URLs: clusterUrlSlice, KeyPrefix: key, diff --git a/router/core/router.go b/router/core/router.go index f72c302c99..563320612f 100644 --- a/router/core/router.go +++ b/router/core/router.go @@ -6,6 +6,13 @@ import ( "crypto/x509" "errors" "fmt" + "github.com/wundergraph/cosmo/router/internal/exporter" + "github.com/wundergraph/cosmo/router/internal/normalizationcachewarmupexporter" + "github.com/wundergraph/cosmo/router/internal/persistedoperation/apq" + "github.com/wundergraph/cosmo/router/internal/persistedoperation/operationstorage/cdn" + "github.com/wundergraph/cosmo/router/internal/persistedoperation/operationstorage/s3" + "github.com/wundergraph/graphql-go-tools/v2/pkg/netpoll" + "go.opentelemetry.io/otel/propagation" "net" "net/http" "net/url" diff --git a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index 0b1b972e94..97c36560e3 100644 --- a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -963,8 +963,10 @@ type NormalizationCacheWarmupDataQuery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Query is the original query sent by the client Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` - Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` + // Hash is the hash of the fully normalized query + Hash uint64 `protobuf:"varint,2,opt,name=Hash,proto3" json:"Hash,omitempty"` } func (x *NormalizationCacheWarmupDataQuery) Reset() { diff --git a/router/gen/proto/wg/cosmo/node/v1/node.pb.go b/router/gen/proto/wg/cosmo/node/v1/node.pb.go index 650926febc..07f9ba175e 100644 --- a/router/gen/proto/wg/cosmo/node/v1/node.pb.go +++ b/router/gen/proto/wg/cosmo/node/v1/node.pb.go @@ -3127,6 +3127,11 @@ type OperationRequest struct { OperationName string `protobuf:"bytes,1,opt,name=operation_name,json=operationName,proto3" json:"operation_name,omitempty"` Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` Extensions *Extension `protobuf:"bytes,3,opt,name=extensions,proto3" json:"extensions,omitempty"` + // we're only interested in variables that are relevant for normalization + // as such, we only need booleans that are used for skip/include + // consequently, variables is a map of key->bool + Variables map[string]bool `protobuf:"bytes,4,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + VariableVariations []*VariableVariation `protobuf:"bytes,5,rep,name=variable_variations,json=variableVariations,proto3" json:"variable_variations,omitempty"` } func (x *OperationRequest) Reset() { @@ -3182,6 +3187,67 @@ func (x *OperationRequest) GetExtensions() *Extension { return nil } +func (x *OperationRequest) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + +func (x *OperationRequest) GetVariableVariations() []*VariableVariation { + if x != nil { + return x.VariableVariations + } + return nil +} + +type VariableVariation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Variables map[string]bool `protobuf:"bytes,1,rep,name=variables,proto3" json:"variables,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *VariableVariation) Reset() { + *x = VariableVariation{} + if protoimpl.UnsafeEnabled { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VariableVariation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VariableVariation) ProtoMessage() {} + +func (x *VariableVariation) ProtoReflect() protoreflect.Message { + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + 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 VariableVariation.ProtoReflect.Descriptor instead. +func (*VariableVariation) Descriptor() ([]byte, []int) { + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} +} + +func (x *VariableVariation) GetVariables() map[string]bool { + if x != nil { + return x.Variables + } + return nil +} + type Extension struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3193,7 +3259,7 @@ type Extension struct { func (x *Extension) Reset() { *x = Extension{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3206,7 +3272,7 @@ func (x *Extension) String() string { func (*Extension) ProtoMessage() {} func (x *Extension) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[45] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3219,7 +3285,7 @@ func (x *Extension) ProtoReflect() protoreflect.Message { // Deprecated: Use Extension.ProtoReflect.Descriptor instead. func (*Extension) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{45} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} } func (x *Extension) GetPersistedQuery() *PersistedQuery { @@ -3241,7 +3307,7 @@ type PersistedQuery struct { func (x *PersistedQuery) Reset() { *x = PersistedQuery{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3254,7 +3320,7 @@ func (x *PersistedQuery) String() string { func (*PersistedQuery) ProtoMessage() {} func (x *PersistedQuery) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[46] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3267,7 +3333,7 @@ func (x *PersistedQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PersistedQuery.ProtoReflect.Descriptor instead. func (*PersistedQuery) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{46} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} } func (x *PersistedQuery) GetSha256Hash() string { @@ -3296,7 +3362,7 @@ type ClientInfo struct { func (x *ClientInfo) Reset() { *x = ClientInfo{} if protoimpl.UnsafeEnabled { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3309,7 +3375,7 @@ func (x *ClientInfo) String() string { func (*ClientInfo) ProtoMessage() {} func (x *ClientInfo) ProtoReflect() protoreflect.Message { - mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[47] + mi := &file_wg_cosmo_node_v1_node_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3322,7 +3388,7 @@ func (x *ClientInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. func (*ClientInfo) Descriptor() ([]byte, []int) { - return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{47} + return file_wg_cosmo_node_v1_node_proto_rawDescGZIP(), []int{48} } func (x *ClientInfo) GetName() string { @@ -3912,7 +3978,7 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0xf1, 0x02, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x70, 0x65, 0x72, @@ -3921,73 +3987,98 @@ var file_wg_cosmo_node_v1_node_proto_rawDesc = []byte{ 0x3b, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x09, - 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x22, 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, - 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x22, 0x3a, 0x0a, 0x0a, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, - 0x0a, 0x1b, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, - 0x17, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, - 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, - 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, - 0x5f, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, - 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, - 0x10, 0x02, 0x2a, 0x36, 0x0a, 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, - 0x49, 0x45, 0x4c, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, - 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, - 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, - 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, - 0x48, 0x51, 0x4c, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, - 0x02, 0x2a, 0x34, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, - 0x0a, 0x07, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, - 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, - 0x43, 0x52, 0x49, 0x42, 0x45, 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, - 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, - 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, - 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, - 0x45, 0x48, 0x4f, 0x4c, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, - 0x2a, 0x41, 0x0a, 0x0a, 0x48, 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, - 0x0a, 0x03, 0x47, 0x45, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, - 0x01, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, - 0x53, 0x10, 0x04, 0x32, 0x6e, 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x5f, 0x0a, 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x12, 0x25, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, - 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, - 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0xcb, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, - 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, - 0x68, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, - 0xa2, 0x02, 0x03, 0x57, 0x43, 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, - 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, - 0x3a, 0x3a, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x09, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x54, 0x0a, + 0x13, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x12, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xa3, 0x01, 0x0a, 0x11, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x77, 0x67, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x3c, 0x0a, 0x0e, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 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, 0x08, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0f, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, + 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x0e, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x22, + 0x4b, 0x0a, 0x0e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x64, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0a, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x82, 0x01, 0x0a, 0x1b, 0x41, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x4e, 0x44, + 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, + 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x53, 0x5f, 0x47, 0x52, 0x41, 0x50, + 0x48, 0x51, 0x4c, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, + 0x53, 0x5f, 0x41, 0x52, 0x52, 0x41, 0x59, 0x5f, 0x43, 0x53, 0x56, 0x10, 0x02, 0x2a, 0x36, 0x0a, + 0x0e, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x10, 0x0a, 0x0c, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, + 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, 0x4d, + 0x45, 0x4e, 0x54, 0x10, 0x01, 0x2a, 0x35, 0x0a, 0x0e, 0x44, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x41, 0x54, 0x49, + 0x43, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x41, 0x50, 0x48, 0x51, 0x4c, 0x10, 0x01, + 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x53, 0x55, 0x42, 0x10, 0x02, 0x2a, 0x34, 0x0a, 0x09, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x55, 0x42, + 0x4c, 0x49, 0x53, 0x48, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, + 0x54, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x42, 0x45, + 0x10, 0x02, 0x2a, 0x86, 0x01, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x69, 0x6e, 0x64, + 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, + 0x45, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x4e, 0x56, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, + 0x45, 0x10, 0x01, 0x12, 0x26, 0x0a, 0x22, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x48, 0x4f, 0x4c, 0x44, + 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x02, 0x2a, 0x41, 0x0a, 0x0a, 0x48, + 0x54, 0x54, 0x50, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x45, 0x54, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x10, 0x04, 0x32, 0x6e, + 0x0a, 0x0b, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, + 0x0c, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x25, 0x2e, + 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xcb, + 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x77, 0x67, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x77, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x67, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, + 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x57, 0x43, + 0x4e, 0xaa, 0x02, 0x10, 0x57, 0x67, 0x2e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x2e, 0x4e, 0x6f, 0x64, + 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x5c, + 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x57, 0x67, 0x5c, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x57, 0x67, 0x3a, 0x3a, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4003,7 +4094,7 @@ func file_wg_cosmo_node_v1_node_proto_rawDescGZIP() []byte { } var file_wg_cosmo_node_v1_node_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 51) +var file_wg_cosmo_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 54) var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (ArgumentRenderConfiguration)(0), // 0: wg.cosmo.node.v1.ArgumentRenderConfiguration (ArgumentSource)(0), // 1: wg.cosmo.node.v1.ArgumentSource @@ -4056,31 +4147,34 @@ var file_wg_cosmo_node_v1_node_proto_goTypes = []any{ (*CacheWarmerOperations)(nil), // 48: wg.cosmo.node.v1.CacheWarmerOperations (*Operation)(nil), // 49: wg.cosmo.node.v1.Operation (*OperationRequest)(nil), // 50: wg.cosmo.node.v1.OperationRequest - (*Extension)(nil), // 51: wg.cosmo.node.v1.Extension - (*PersistedQuery)(nil), // 52: wg.cosmo.node.v1.PersistedQuery - (*ClientInfo)(nil), // 53: wg.cosmo.node.v1.ClientInfo - nil, // 54: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry - nil, // 55: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry - nil, // 56: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry - (common.EnumStatusCode)(0), // 57: wg.cosmo.common.EnumStatusCode - (common.GraphQLSubscriptionProtocol)(0), // 58: wg.cosmo.common.GraphQLSubscriptionProtocol - (common.GraphQLWebsocketSubprotocol)(0), // 59: wg.cosmo.common.GraphQLWebsocketSubprotocol + (*VariableVariation)(nil), // 51: wg.cosmo.node.v1.VariableVariation + (*Extension)(nil), // 52: wg.cosmo.node.v1.Extension + (*PersistedQuery)(nil), // 53: wg.cosmo.node.v1.PersistedQuery + (*ClientInfo)(nil), // 54: wg.cosmo.node.v1.ClientInfo + nil, // 55: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + nil, // 56: wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + nil, // 57: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + nil, // 58: wg.cosmo.node.v1.OperationRequest.VariablesEntry + nil, // 59: wg.cosmo.node.v1.VariableVariation.VariablesEntry + (common.EnumStatusCode)(0), // 60: wg.cosmo.common.EnumStatusCode + (common.GraphQLSubscriptionProtocol)(0), // 61: wg.cosmo.common.GraphQLSubscriptionProtocol + (common.GraphQLWebsocketSubprotocol)(0), // 62: wg.cosmo.common.GraphQLWebsocketSubprotocol } var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ - 54, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry + 55, // 0: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.config_by_feature_flag_name:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry 16, // 1: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 2: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 16, // 3: wg.cosmo.node.v1.RouterConfig.engine_config:type_name -> wg.cosmo.node.v1.EngineConfiguration 6, // 4: wg.cosmo.node.v1.RouterConfig.subgraphs:type_name -> wg.cosmo.node.v1.Subgraph 7, // 5: wg.cosmo.node.v1.RouterConfig.feature_flag_configs:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs - 57, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode + 60, // 6: wg.cosmo.node.v1.Response.code:type_name -> wg.cosmo.common.EnumStatusCode 13, // 7: wg.cosmo.node.v1.RegistrationInfo.account_limits:type_name -> wg.cosmo.node.v1.AccountLimits 10, // 8: wg.cosmo.node.v1.SelfRegisterResponse.response:type_name -> wg.cosmo.node.v1.Response 12, // 9: wg.cosmo.node.v1.SelfRegisterResponse.registrationInfo:type_name -> wg.cosmo.node.v1.RegistrationInfo 17, // 10: wg.cosmo.node.v1.EngineConfiguration.datasource_configurations:type_name -> wg.cosmo.node.v1.DataSourceConfiguration 21, // 11: wg.cosmo.node.v1.EngineConfiguration.field_configurations:type_name -> wg.cosmo.node.v1.FieldConfiguration 22, // 12: wg.cosmo.node.v1.EngineConfiguration.type_configurations:type_name -> wg.cosmo.node.v1.TypeConfiguration - 55, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry + 56, // 13: wg.cosmo.node.v1.EngineConfiguration.string_storage:type_name -> wg.cosmo.node.v1.EngineConfiguration.StringStorageEntry 2, // 14: wg.cosmo.node.v1.DataSourceConfiguration.kind:type_name -> wg.cosmo.node.v1.DataSourceKind 23, // 15: wg.cosmo.node.v1.DataSourceConfiguration.root_nodes:type_name -> wg.cosmo.node.v1.TypeField 23, // 16: wg.cosmo.node.v1.DataSourceConfiguration.child_nodes:type_name -> wg.cosmo.node.v1.TypeField @@ -4102,7 +4196,7 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 25, // 32: wg.cosmo.node.v1.RequiredField.conditions:type_name -> wg.cosmo.node.v1.FieldSetCondition 37, // 33: wg.cosmo.node.v1.FetchConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable 5, // 34: wg.cosmo.node.v1.FetchConfiguration.method:type_name -> wg.cosmo.node.v1.HTTPMethod - 56, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry + 57, // 35: wg.cosmo.node.v1.FetchConfiguration.header:type_name -> wg.cosmo.node.v1.FetchConfiguration.HeaderEntry 37, // 36: wg.cosmo.node.v1.FetchConfiguration.body:type_name -> wg.cosmo.node.v1.ConfigurationVariable 39, // 37: wg.cosmo.node.v1.FetchConfiguration.query:type_name -> wg.cosmo.node.v1.URLQueryConfiguration 41, // 38: wg.cosmo.node.v1.FetchConfiguration.mtls:type_name -> wg.cosmo.node.v1.MTLSConfiguration @@ -4126,26 +4220,29 @@ var file_wg_cosmo_node_v1_node_proto_depIdxs = []int32{ 37, // 56: wg.cosmo.node.v1.MTLSConfiguration.key:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 57: wg.cosmo.node.v1.MTLSConfiguration.cert:type_name -> wg.cosmo.node.v1.ConfigurationVariable 37, // 58: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.url:type_name -> wg.cosmo.node.v1.ConfigurationVariable - 58, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol - 59, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol + 61, // 59: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.protocol:type_name -> wg.cosmo.common.GraphQLSubscriptionProtocol + 62, // 60: wg.cosmo.node.v1.GraphQLSubscriptionConfiguration.websocketSubprotocol:type_name -> wg.cosmo.common.GraphQLWebsocketSubprotocol 47, // 61: wg.cosmo.node.v1.SubscriptionFilterCondition.and:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 46, // 62: wg.cosmo.node.v1.SubscriptionFilterCondition.in:type_name -> wg.cosmo.node.v1.SubscriptionFieldCondition 47, // 63: wg.cosmo.node.v1.SubscriptionFilterCondition.not:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 47, // 64: wg.cosmo.node.v1.SubscriptionFilterCondition.or:type_name -> wg.cosmo.node.v1.SubscriptionFilterCondition 49, // 65: wg.cosmo.node.v1.CacheWarmerOperations.operations:type_name -> wg.cosmo.node.v1.Operation 50, // 66: wg.cosmo.node.v1.Operation.request:type_name -> wg.cosmo.node.v1.OperationRequest - 53, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo - 51, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension - 52, // 69: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery - 8, // 70: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig - 40, // 71: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader - 14, // 72: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest - 15, // 73: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse - 73, // [73:74] is the sub-list for method output_type - 72, // [72:73] is the sub-list for method input_type - 72, // [72:72] is the sub-list for extension type_name - 72, // [72:72] is the sub-list for extension extendee - 0, // [0:72] is the sub-list for field type_name + 54, // 67: wg.cosmo.node.v1.Operation.client:type_name -> wg.cosmo.node.v1.ClientInfo + 52, // 68: wg.cosmo.node.v1.OperationRequest.extensions:type_name -> wg.cosmo.node.v1.Extension + 58, // 69: wg.cosmo.node.v1.OperationRequest.variables:type_name -> wg.cosmo.node.v1.OperationRequest.VariablesEntry + 51, // 70: wg.cosmo.node.v1.OperationRequest.variable_variations:type_name -> wg.cosmo.node.v1.VariableVariation + 59, // 71: wg.cosmo.node.v1.VariableVariation.variables:type_name -> wg.cosmo.node.v1.VariableVariation.VariablesEntry + 53, // 72: wg.cosmo.node.v1.Extension.persisted_query:type_name -> wg.cosmo.node.v1.PersistedQuery + 8, // 73: wg.cosmo.node.v1.FeatureFlagRouterExecutionConfigs.ConfigByFeatureFlagNameEntry.value:type_name -> wg.cosmo.node.v1.FeatureFlagRouterExecutionConfig + 40, // 74: wg.cosmo.node.v1.FetchConfiguration.HeaderEntry.value:type_name -> wg.cosmo.node.v1.HTTPHeader + 14, // 75: wg.cosmo.node.v1.NodeService.SelfRegister:input_type -> wg.cosmo.node.v1.SelfRegisterRequest + 15, // 76: wg.cosmo.node.v1.NodeService.SelfRegister:output_type -> wg.cosmo.node.v1.SelfRegisterResponse + 76, // [76:77] is the sub-list for method output_type + 75, // [75:76] is the sub-list for method input_type + 75, // [75:75] is the sub-list for extension type_name + 75, // [75:75] is the sub-list for extension extendee + 0, // [0:75] is the sub-list for field type_name } func init() { file_wg_cosmo_node_v1_node_proto_init() } @@ -4695,7 +4792,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*Extension); i { + switch v := v.(*VariableVariation); i { case 0: return &v.state case 1: @@ -4707,7 +4804,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*PersistedQuery); i { + switch v := v.(*Extension); i { case 0: return &v.state case 1: @@ -4719,6 +4816,18 @@ func file_wg_cosmo_node_v1_node_proto_init() { } } file_wg_cosmo_node_v1_node_proto_msgTypes[47].Exporter = func(v any, i int) any { + switch v := v.(*PersistedQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_wg_cosmo_node_v1_node_proto_msgTypes[48].Exporter = func(v any, i int) any { switch v := v.(*ClientInfo); i { case 0: return &v.state @@ -4745,7 +4854,7 @@ func file_wg_cosmo_node_v1_node_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_wg_cosmo_node_v1_node_proto_rawDesc, NumEnums: 6, - NumMessages: 51, + NumMessages: 54, NumExtensions: 0, NumServices: 1, },