From 62325ba8e777977f4e319388ae93ee8c94084524 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Thu, 5 Dec 2024 14:03:42 +1100 Subject: [PATCH] feat: add filters and ordering to timeline service (#3635) closes #3628 - Proto filters copied from `console.pb` - In-memory filters based on `backend/controller/timeline/query.go` --------- Co-authored-by: github-actions[bot] --- .../xyz/block/ftl/timeline/v1/timeline.pb.go | 1190 ++++++++++++++--- .../xyz/block/ftl/timeline/v1/timeline.proto | 74 +- backend/timeline/events.go | 68 - backend/timeline/filters.go | 272 ++++ backend/timeline/service.go | 47 +- backend/timeline/service_test.go | 21 +- .../xyz/block/ftl/timeline/v1/timeline_pb.ts | 538 +++++++- .../xyz/block/ftl/timeline/v1/timeline_pb2.py | 53 +- .../block/ftl/timeline/v1/timeline_pb2.pyi | 100 +- 9 files changed, 2059 insertions(+), 304 deletions(-) delete mode 100644 backend/timeline/events.go create mode 100644 backend/timeline/filters.go diff --git a/backend/protos/xyz/block/ftl/timeline/v1/timeline.pb.go b/backend/protos/xyz/block/ftl/timeline/v1/timeline.pb.go index 57935d5d58..b4532f1282 100644 --- a/backend/protos/xyz/block/ftl/timeline/v1/timeline.pb.go +++ b/backend/protos/xyz/block/ftl/timeline/v1/timeline.pb.go @@ -10,6 +10,7 @@ import ( v1 "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -21,15 +22,63 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type GetTimelineRequest_Order int32 + +const ( + GetTimelineRequest_ORDER_UNSPECIFIED GetTimelineRequest_Order = 0 + GetTimelineRequest_ORDER_ASC GetTimelineRequest_Order = 1 + GetTimelineRequest_ORDER_DESC GetTimelineRequest_Order = 2 +) + +// Enum value maps for GetTimelineRequest_Order. +var ( + GetTimelineRequest_Order_name = map[int32]string{ + 0: "ORDER_UNSPECIFIED", + 1: "ORDER_ASC", + 2: "ORDER_DESC", + } + GetTimelineRequest_Order_value = map[string]int32{ + "ORDER_UNSPECIFIED": 0, + "ORDER_ASC": 1, + "ORDER_DESC": 2, + } +) + +func (x GetTimelineRequest_Order) Enum() *GetTimelineRequest_Order { + p := new(GetTimelineRequest_Order) + *p = x + return p +} + +func (x GetTimelineRequest_Order) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GetTimelineRequest_Order) Descriptor() protoreflect.EnumDescriptor { + return file_xyz_block_ftl_timeline_v1_timeline_proto_enumTypes[0].Descriptor() +} + +func (GetTimelineRequest_Order) Type() protoreflect.EnumType { + return &file_xyz_block_ftl_timeline_v1_timeline_proto_enumTypes[0] +} + +func (x GetTimelineRequest_Order) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GetTimelineRequest_Order.Descriptor instead. +func (GetTimelineRequest_Order) EnumDescriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 0} +} + type GetTimelineRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - DeploymentKey string `protobuf:"bytes,1,opt,name=deployment_key,json=deploymentKey,proto3" json:"deployment_key,omitempty"` - SinceId *int64 `protobuf:"varint,2,opt,name=since_id,json=sinceId,proto3,oneof" json:"since_id,omitempty"` - Limit *int32 `protobuf:"varint,3,opt,name=limit,proto3,oneof" json:"limit,omitempty"` - EventTypes []EventType `protobuf:"varint,4,rep,packed,name=event_types,json=eventTypes,proto3,enum=xyz.block.ftl.timeline.v1.EventType" json:"event_types,omitempty"` + Filters []*GetTimelineRequest_Filter `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` + Limit int32 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + Order GetTimelineRequest_Order `protobuf:"varint,3,opt,name=order,proto3,enum=xyz.block.ftl.timeline.v1.GetTimelineRequest_Order" json:"order,omitempty"` } func (x *GetTimelineRequest) Reset() { @@ -62,32 +111,25 @@ func (*GetTimelineRequest) Descriptor() ([]byte, []int) { return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0} } -func (x *GetTimelineRequest) GetDeploymentKey() string { +func (x *GetTimelineRequest) GetFilters() []*GetTimelineRequest_Filter { if x != nil { - return x.DeploymentKey - } - return "" -} - -func (x *GetTimelineRequest) GetSinceId() int64 { - if x != nil && x.SinceId != nil { - return *x.SinceId + return x.Filters } - return 0 + return nil } func (x *GetTimelineRequest) GetLimit() int32 { - if x != nil && x.Limit != nil { - return *x.Limit + if x != nil { + return x.Limit } return 0 } -func (x *GetTimelineRequest) GetEventTypes() []EventType { +func (x *GetTimelineRequest) GetOrder() GetTimelineRequest_Order { if x != nil { - return x.EventTypes + return x.Order } - return nil + return GetTimelineRequest_ORDER_UNSPECIFIED } type GetTimelineResponse struct { @@ -446,6 +488,642 @@ func (x *DeleteOldEventsResponse) GetDeletedCount() int64 { return 0 } +// Limit the number of events returned. +type GetTimelineRequest_LimitFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Limit int32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` +} + +func (x *GetTimelineRequest_LimitFilter) Reset() { + *x = GetTimelineRequest_LimitFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_LimitFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_LimitFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_LimitFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_LimitFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_LimitFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *GetTimelineRequest_LimitFilter) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +// Filters events by log level. +type GetTimelineRequest_LogLevelFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LogLevel LogLevel `protobuf:"varint,1,opt,name=log_level,json=logLevel,proto3,enum=xyz.block.ftl.timeline.v1.LogLevel" json:"log_level,omitempty"` +} + +func (x *GetTimelineRequest_LogLevelFilter) Reset() { + *x = GetTimelineRequest_LogLevelFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_LogLevelFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_LogLevelFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_LogLevelFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_LogLevelFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_LogLevelFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *GetTimelineRequest_LogLevelFilter) GetLogLevel() LogLevel { + if x != nil { + return x.LogLevel + } + return LogLevel_LOG_LEVEL_UNSPECIFIED +} + +// Filters events by deployment key. +type GetTimelineRequest_DeploymentFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Deployments []string `protobuf:"bytes,1,rep,name=deployments,proto3" json:"deployments,omitempty"` +} + +func (x *GetTimelineRequest_DeploymentFilter) Reset() { + *x = GetTimelineRequest_DeploymentFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_DeploymentFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_DeploymentFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_DeploymentFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_DeploymentFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_DeploymentFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *GetTimelineRequest_DeploymentFilter) GetDeployments() []string { + if x != nil { + return x.Deployments + } + return nil +} + +// Filters events by request key. +type GetTimelineRequest_RequestFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Requests []string `protobuf:"bytes,1,rep,name=requests,proto3" json:"requests,omitempty"` +} + +func (x *GetTimelineRequest_RequestFilter) Reset() { + *x = GetTimelineRequest_RequestFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_RequestFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_RequestFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_RequestFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_RequestFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_RequestFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *GetTimelineRequest_RequestFilter) GetRequests() []string { + if x != nil { + return x.Requests + } + return nil +} + +// Filters events by event type. +type GetTimelineRequest_EventTypeFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EventTypes []EventType `protobuf:"varint,1,rep,packed,name=event_types,json=eventTypes,proto3,enum=xyz.block.ftl.timeline.v1.EventType" json:"event_types,omitempty"` +} + +func (x *GetTimelineRequest_EventTypeFilter) Reset() { + *x = GetTimelineRequest_EventTypeFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_EventTypeFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_EventTypeFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_EventTypeFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_EventTypeFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_EventTypeFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *GetTimelineRequest_EventTypeFilter) GetEventTypes() []EventType { + if x != nil { + return x.EventTypes + } + return nil +} + +// Filters events by time. +// +// Either end of the time range can be omitted to indicate no bound. +type GetTimelineRequest_TimeFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OlderThan *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=older_than,json=olderThan,proto3,oneof" json:"older_than,omitempty"` + NewerThan *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=newer_than,json=newerThan,proto3,oneof" json:"newer_than,omitempty"` +} + +func (x *GetTimelineRequest_TimeFilter) Reset() { + *x = GetTimelineRequest_TimeFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_TimeFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_TimeFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_TimeFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_TimeFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_TimeFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *GetTimelineRequest_TimeFilter) GetOlderThan() *timestamppb.Timestamp { + if x != nil { + return x.OlderThan + } + return nil +} + +func (x *GetTimelineRequest_TimeFilter) GetNewerThan() *timestamppb.Timestamp { + if x != nil { + return x.NewerThan + } + return nil +} + +// Filters events by ID. +// +// Either end of the ID range can be omitted to indicate no bound. +type GetTimelineRequest_IDFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LowerThan *int64 `protobuf:"varint,1,opt,name=lower_than,json=lowerThan,proto3,oneof" json:"lower_than,omitempty"` + HigherThan *int64 `protobuf:"varint,2,opt,name=higher_than,json=higherThan,proto3,oneof" json:"higher_than,omitempty"` +} + +func (x *GetTimelineRequest_IDFilter) Reset() { + *x = GetTimelineRequest_IDFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_IDFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_IDFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_IDFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_IDFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_IDFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 6} +} + +func (x *GetTimelineRequest_IDFilter) GetLowerThan() int64 { + if x != nil && x.LowerThan != nil { + return *x.LowerThan + } + return 0 +} + +func (x *GetTimelineRequest_IDFilter) GetHigherThan() int64 { + if x != nil && x.HigherThan != nil { + return *x.HigherThan + } + return 0 +} + +// Filters events by call. +type GetTimelineRequest_CallFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DestModule string `protobuf:"bytes,1,opt,name=dest_module,json=destModule,proto3" json:"dest_module,omitempty"` + DestVerb *string `protobuf:"bytes,2,opt,name=dest_verb,json=destVerb,proto3,oneof" json:"dest_verb,omitempty"` + SourceModule *string `protobuf:"bytes,3,opt,name=source_module,json=sourceModule,proto3,oneof" json:"source_module,omitempty"` +} + +func (x *GetTimelineRequest_CallFilter) Reset() { + *x = GetTimelineRequest_CallFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_CallFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_CallFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_CallFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_CallFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_CallFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 7} +} + +func (x *GetTimelineRequest_CallFilter) GetDestModule() string { + if x != nil { + return x.DestModule + } + return "" +} + +func (x *GetTimelineRequest_CallFilter) GetDestVerb() string { + if x != nil && x.DestVerb != nil { + return *x.DestVerb + } + return "" +} + +func (x *GetTimelineRequest_CallFilter) GetSourceModule() string { + if x != nil && x.SourceModule != nil { + return *x.SourceModule + } + return "" +} + +type GetTimelineRequest_ModuleFilter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` + Verb *string `protobuf:"bytes,2,opt,name=verb,proto3,oneof" json:"verb,omitempty"` +} + +func (x *GetTimelineRequest_ModuleFilter) Reset() { + *x = GetTimelineRequest_ModuleFilter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_ModuleFilter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_ModuleFilter) ProtoMessage() {} + +func (x *GetTimelineRequest_ModuleFilter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_ModuleFilter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_ModuleFilter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 8} +} + +func (x *GetTimelineRequest_ModuleFilter) GetModule() string { + if x != nil { + return x.Module + } + return "" +} + +func (x *GetTimelineRequest_ModuleFilter) GetVerb() string { + if x != nil && x.Verb != nil { + return *x.Verb + } + return "" +} + +type GetTimelineRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // These map 1:1 with filters in backend/timeline/filters.go + // + // Types that are assignable to Filter: + // + // *GetTimelineRequest_Filter_Limit + // *GetTimelineRequest_Filter_LogLevel + // *GetTimelineRequest_Filter_Deployments + // *GetTimelineRequest_Filter_Requests + // *GetTimelineRequest_Filter_EventTypes + // *GetTimelineRequest_Filter_Time + // *GetTimelineRequest_Filter_Id + // *GetTimelineRequest_Filter_Call + // *GetTimelineRequest_Filter_Module + Filter isGetTimelineRequest_Filter_Filter `protobuf_oneof:"filter"` +} + +func (x *GetTimelineRequest_Filter) Reset() { + *x = GetTimelineRequest_Filter{} + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimelineRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimelineRequest_Filter) ProtoMessage() {} + +func (x *GetTimelineRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTimelineRequest_Filter.ProtoReflect.Descriptor instead. +func (*GetTimelineRequest_Filter) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP(), []int{0, 9} +} + +func (m *GetTimelineRequest_Filter) GetFilter() isGetTimelineRequest_Filter_Filter { + if m != nil { + return m.Filter + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetLimit() *GetTimelineRequest_LimitFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Limit); ok { + return x.Limit + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetLogLevel() *GetTimelineRequest_LogLevelFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_LogLevel); ok { + return x.LogLevel + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetDeployments() *GetTimelineRequest_DeploymentFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Deployments); ok { + return x.Deployments + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetRequests() *GetTimelineRequest_RequestFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Requests); ok { + return x.Requests + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetEventTypes() *GetTimelineRequest_EventTypeFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_EventTypes); ok { + return x.EventTypes + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetTime() *GetTimelineRequest_TimeFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Time); ok { + return x.Time + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetId() *GetTimelineRequest_IDFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Id); ok { + return x.Id + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetCall() *GetTimelineRequest_CallFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Call); ok { + return x.Call + } + return nil +} + +func (x *GetTimelineRequest_Filter) GetModule() *GetTimelineRequest_ModuleFilter { + if x, ok := x.GetFilter().(*GetTimelineRequest_Filter_Module); ok { + return x.Module + } + return nil +} + +type isGetTimelineRequest_Filter_Filter interface { + isGetTimelineRequest_Filter_Filter() +} + +type GetTimelineRequest_Filter_Limit struct { + Limit *GetTimelineRequest_LimitFilter `protobuf:"bytes,1,opt,name=limit,proto3,oneof"` +} + +type GetTimelineRequest_Filter_LogLevel struct { + LogLevel *GetTimelineRequest_LogLevelFilter `protobuf:"bytes,2,opt,name=log_level,json=logLevel,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Deployments struct { + Deployments *GetTimelineRequest_DeploymentFilter `protobuf:"bytes,3,opt,name=deployments,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Requests struct { + Requests *GetTimelineRequest_RequestFilter `protobuf:"bytes,4,opt,name=requests,proto3,oneof"` +} + +type GetTimelineRequest_Filter_EventTypes struct { + EventTypes *GetTimelineRequest_EventTypeFilter `protobuf:"bytes,5,opt,name=event_types,json=eventTypes,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Time struct { + Time *GetTimelineRequest_TimeFilter `protobuf:"bytes,6,opt,name=time,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Id struct { + Id *GetTimelineRequest_IDFilter `protobuf:"bytes,7,opt,name=id,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Call struct { + Call *GetTimelineRequest_CallFilter `protobuf:"bytes,8,opt,name=call,proto3,oneof"` +} + +type GetTimelineRequest_Filter_Module struct { + Module *GetTimelineRequest_ModuleFilter `protobuf:"bytes,9,opt,name=module,proto3,oneof"` +} + +func (*GetTimelineRequest_Filter_Limit) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_LogLevel) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Deployments) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Requests) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_EventTypes) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Time) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Id) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Call) isGetTimelineRequest_Filter_Filter() {} + +func (*GetTimelineRequest_Filter_Module) isGetTimelineRequest_Filter_Filter() {} + var File_xyz_block_ftl_timeline_v1_timeline_proto protoreflect.FileDescriptor var file_xyz_block_ftl_timeline_v1_timeline_proto_rawDesc = []byte{ @@ -453,125 +1131,232 @@ var file_xyz_block_ftl_timeline_v1_timeline_proto_rawDesc = []byte{ 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x25, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, - 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x78, 0x79, - 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x66, - 0x74, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd4, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x08, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x07, 0x73, 0x69, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, - 0x01, 0x12, 0x45, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x73, 0x69, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, - 0x4f, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x22, 0xfc, 0x05, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, - 0x12, 0x3a, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, - 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x62, 0x0a, 0x12, - 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x12, 0x62, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, - 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, - 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, + 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x78, + 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x2f, + 0x66, 0x74, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x0e, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x4e, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x49, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x1a, 0x23, 0x0a, 0x0b, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x1a, 0x52, 0x0a, 0x0e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, + 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, + 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x34, 0x0a, 0x10, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x1a, 0x2b, 0x0a, 0x0d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x1a, 0x58, 0x0a, + 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x45, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x56, 0x0a, 0x0e, 0x63, 0x72, 0x6f, - 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x48, 0x00, 0x52, 0x0d, 0x63, 0x72, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x64, 0x12, 0x53, 0x0a, 0x0d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, - 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, + 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x1a, 0xaa, 0x01, 0x0a, 0x0a, 0x54, 0x69, 0x6d, 0x65, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0a, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x68, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x54, + 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x3e, 0x0a, 0x0a, 0x6e, 0x65, 0x77, 0x65, 0x72, 0x5f, + 0x74, 0x68, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x01, 0x52, 0x09, 0x6e, 0x65, 0x77, 0x65, 0x72, 0x54, + 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x6e, 0x65, 0x77, 0x65, 0x72, 0x5f, + 0x74, 0x68, 0x61, 0x6e, 0x1a, 0x73, 0x0a, 0x08, 0x49, 0x44, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x12, 0x22, 0x0a, 0x0a, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x54, 0x68, 0x61, + 0x6e, 0x88, 0x01, 0x01, 0x12, 0x24, 0x0a, 0x0b, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x5f, 0x74, + 0x68, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x0a, 0x68, 0x69, 0x67, + 0x68, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x6c, + 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x68, 0x69, + 0x67, 0x68, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x61, 0x6e, 0x1a, 0x99, 0x01, 0x0a, 0x0a, 0x43, 0x61, + 0x6c, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, + 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, + 0x65, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x09, 0x64, 0x65, 0x73, + 0x74, 0x5f, 0x76, 0x65, 0x72, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, + 0x64, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x62, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x5f, 0x76, + 0x65, 0x72, 0x62, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x1a, 0x48, 0x0a, 0x0c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x17, 0x0a, + 0x04, 0x76, 0x65, 0x72, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x76, + 0x65, 0x72, 0x62, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x76, 0x65, 0x72, 0x62, 0x1a, + 0xa3, 0x06, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x5b, 0x0a, + 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3c, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, + 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, + 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x62, 0x0a, 0x0b, 0x64, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x0b, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x59, + 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3b, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, + 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x60, 0x0a, 0x0b, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, - 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x53, 0x75, - 0x62, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0d, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x56, - 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x53, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, - 0x15, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x43, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x63, - 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x67, 0x65, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x3e, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xbc, 0x03, 0x0a, 0x0f, 0x54, 0x69, 0x6d, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x04, 0x50, 0x69, - 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x71, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x04, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x48, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x44, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, + 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4e, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, + 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x54, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x6e, 0x0a, 0x0b, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, 0x0a, 0x0f, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x78, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x3d, 0x0a, 0x05, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x15, + 0x0a, 0x11, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x41, + 0x53, 0x43, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x44, 0x45, + 0x53, 0x43, 0x10, 0x02, 0x22, 0x4f, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xfc, 0x05, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x03, + 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, + 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x3a, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x04, 0x63, 0x61, 0x6c, + 0x6c, 0x12, 0x62, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, + 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x62, 0x0a, 0x12, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x11, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x07, 0x69, 0x6e, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x56, + 0x0a, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x72, 0x6f, 0x6e, 0x53, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x12, 0x53, 0x0a, 0x0d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x5f, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, + 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x61, + 0x73, 0x79, 0x6e, 0x63, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x0e, 0x70, + 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x75, 0x62, 0x53, 0x75, 0x62, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x73, 0x68, 0x12, 0x56, 0x0a, 0x0e, 0x70, 0x75, 0x62, 0x73, 0x75, 0x62, 0x5f, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x62, 0x53, 0x75, 0x62, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x75, + 0x62, 0x73, 0x75, 0x62, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x22, 0x15, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x67, + 0x65, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0a, 0x61, 0x67, 0x65, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x3e, 0x0a, 0x17, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0xbc, 0x03, 0x0a, 0x0f, + 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x4a, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x71, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x6e, + 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, + 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, - 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, - 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x52, 0x50, 0x01, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, - 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, - 0x74, 0x6c, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x74, - 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7a, + 0x0a, 0x0f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x52, 0x50, 0x01, 0x5a, 0x4e, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, + 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -586,54 +1371,82 @@ func file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescGZIP() []byte { return file_xyz_block_ftl_timeline_v1_timeline_proto_rawDescData } -var file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_xyz_block_ftl_timeline_v1_timeline_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_xyz_block_ftl_timeline_v1_timeline_proto_goTypes = []any{ - (*GetTimelineRequest)(nil), // 0: xyz.block.ftl.timeline.v1.GetTimelineRequest - (*GetTimelineResponse)(nil), // 1: xyz.block.ftl.timeline.v1.GetTimelineResponse - (*CreateEventRequest)(nil), // 2: xyz.block.ftl.timeline.v1.CreateEventRequest - (*CreateEventResponse)(nil), // 3: xyz.block.ftl.timeline.v1.CreateEventResponse - (*DeleteOldEventsRequest)(nil), // 4: xyz.block.ftl.timeline.v1.DeleteOldEventsRequest - (*DeleteOldEventsResponse)(nil), // 5: xyz.block.ftl.timeline.v1.DeleteOldEventsResponse - (EventType)(0), // 6: xyz.block.ftl.timeline.v1.EventType - (*Event)(nil), // 7: xyz.block.ftl.timeline.v1.Event - (*LogEvent)(nil), // 8: xyz.block.ftl.timeline.v1.LogEvent - (*CallEvent)(nil), // 9: xyz.block.ftl.timeline.v1.CallEvent - (*DeploymentCreatedEvent)(nil), // 10: xyz.block.ftl.timeline.v1.DeploymentCreatedEvent - (*DeploymentUpdatedEvent)(nil), // 11: xyz.block.ftl.timeline.v1.DeploymentUpdatedEvent - (*IngressEvent)(nil), // 12: xyz.block.ftl.timeline.v1.IngressEvent - (*CronScheduledEvent)(nil), // 13: xyz.block.ftl.timeline.v1.CronScheduledEvent - (*AsyncExecuteEvent)(nil), // 14: xyz.block.ftl.timeline.v1.AsyncExecuteEvent - (*PubSubPublishEvent)(nil), // 15: xyz.block.ftl.timeline.v1.PubSubPublishEvent - (*PubSubConsumeEvent)(nil), // 16: xyz.block.ftl.timeline.v1.PubSubConsumeEvent - (*v1.PingRequest)(nil), // 17: xyz.block.ftl.v1.PingRequest - (*v1.PingResponse)(nil), // 18: xyz.block.ftl.v1.PingResponse + (GetTimelineRequest_Order)(0), // 0: xyz.block.ftl.timeline.v1.GetTimelineRequest.Order + (*GetTimelineRequest)(nil), // 1: xyz.block.ftl.timeline.v1.GetTimelineRequest + (*GetTimelineResponse)(nil), // 2: xyz.block.ftl.timeline.v1.GetTimelineResponse + (*CreateEventRequest)(nil), // 3: xyz.block.ftl.timeline.v1.CreateEventRequest + (*CreateEventResponse)(nil), // 4: xyz.block.ftl.timeline.v1.CreateEventResponse + (*DeleteOldEventsRequest)(nil), // 5: xyz.block.ftl.timeline.v1.DeleteOldEventsRequest + (*DeleteOldEventsResponse)(nil), // 6: xyz.block.ftl.timeline.v1.DeleteOldEventsResponse + (*GetTimelineRequest_LimitFilter)(nil), // 7: xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilter + (*GetTimelineRequest_LogLevelFilter)(nil), // 8: xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter + (*GetTimelineRequest_DeploymentFilter)(nil), // 9: xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilter + (*GetTimelineRequest_RequestFilter)(nil), // 10: xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilter + (*GetTimelineRequest_EventTypeFilter)(nil), // 11: xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter + (*GetTimelineRequest_TimeFilter)(nil), // 12: xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter + (*GetTimelineRequest_IDFilter)(nil), // 13: xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilter + (*GetTimelineRequest_CallFilter)(nil), // 14: xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilter + (*GetTimelineRequest_ModuleFilter)(nil), // 15: xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilter + (*GetTimelineRequest_Filter)(nil), // 16: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter + (*Event)(nil), // 17: xyz.block.ftl.timeline.v1.Event + (*LogEvent)(nil), // 18: xyz.block.ftl.timeline.v1.LogEvent + (*CallEvent)(nil), // 19: xyz.block.ftl.timeline.v1.CallEvent + (*DeploymentCreatedEvent)(nil), // 20: xyz.block.ftl.timeline.v1.DeploymentCreatedEvent + (*DeploymentUpdatedEvent)(nil), // 21: xyz.block.ftl.timeline.v1.DeploymentUpdatedEvent + (*IngressEvent)(nil), // 22: xyz.block.ftl.timeline.v1.IngressEvent + (*CronScheduledEvent)(nil), // 23: xyz.block.ftl.timeline.v1.CronScheduledEvent + (*AsyncExecuteEvent)(nil), // 24: xyz.block.ftl.timeline.v1.AsyncExecuteEvent + (*PubSubPublishEvent)(nil), // 25: xyz.block.ftl.timeline.v1.PubSubPublishEvent + (*PubSubConsumeEvent)(nil), // 26: xyz.block.ftl.timeline.v1.PubSubConsumeEvent + (EventType)(0), // 27: xyz.block.ftl.timeline.v1.EventType + (LogLevel)(0), // 28: xyz.block.ftl.timeline.v1.LogLevel + (*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp + (*v1.PingRequest)(nil), // 30: xyz.block.ftl.v1.PingRequest + (*v1.PingResponse)(nil), // 31: xyz.block.ftl.v1.PingResponse } var file_xyz_block_ftl_timeline_v1_timeline_proto_depIdxs = []int32{ - 6, // 0: xyz.block.ftl.timeline.v1.GetTimelineRequest.event_types:type_name -> xyz.block.ftl.timeline.v1.EventType - 7, // 1: xyz.block.ftl.timeline.v1.GetTimelineResponse.events:type_name -> xyz.block.ftl.timeline.v1.Event - 8, // 2: xyz.block.ftl.timeline.v1.CreateEventRequest.log:type_name -> xyz.block.ftl.timeline.v1.LogEvent - 9, // 3: xyz.block.ftl.timeline.v1.CreateEventRequest.call:type_name -> xyz.block.ftl.timeline.v1.CallEvent - 10, // 4: xyz.block.ftl.timeline.v1.CreateEventRequest.deployment_created:type_name -> xyz.block.ftl.timeline.v1.DeploymentCreatedEvent - 11, // 5: xyz.block.ftl.timeline.v1.CreateEventRequest.deployment_updated:type_name -> xyz.block.ftl.timeline.v1.DeploymentUpdatedEvent - 12, // 6: xyz.block.ftl.timeline.v1.CreateEventRequest.ingress:type_name -> xyz.block.ftl.timeline.v1.IngressEvent - 13, // 7: xyz.block.ftl.timeline.v1.CreateEventRequest.cron_scheduled:type_name -> xyz.block.ftl.timeline.v1.CronScheduledEvent - 14, // 8: xyz.block.ftl.timeline.v1.CreateEventRequest.async_execute:type_name -> xyz.block.ftl.timeline.v1.AsyncExecuteEvent - 15, // 9: xyz.block.ftl.timeline.v1.CreateEventRequest.pubsub_publish:type_name -> xyz.block.ftl.timeline.v1.PubSubPublishEvent - 16, // 10: xyz.block.ftl.timeline.v1.CreateEventRequest.pubsub_consume:type_name -> xyz.block.ftl.timeline.v1.PubSubConsumeEvent - 6, // 11: xyz.block.ftl.timeline.v1.DeleteOldEventsRequest.event_type:type_name -> xyz.block.ftl.timeline.v1.EventType - 17, // 12: xyz.block.ftl.timeline.v1.TimelineService.Ping:input_type -> xyz.block.ftl.v1.PingRequest - 0, // 13: xyz.block.ftl.timeline.v1.TimelineService.GetTimeline:input_type -> xyz.block.ftl.timeline.v1.GetTimelineRequest - 2, // 14: xyz.block.ftl.timeline.v1.TimelineService.CreateEvent:input_type -> xyz.block.ftl.timeline.v1.CreateEventRequest - 4, // 15: xyz.block.ftl.timeline.v1.TimelineService.DeleteOldEvents:input_type -> xyz.block.ftl.timeline.v1.DeleteOldEventsRequest - 18, // 16: xyz.block.ftl.timeline.v1.TimelineService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 1, // 17: xyz.block.ftl.timeline.v1.TimelineService.GetTimeline:output_type -> xyz.block.ftl.timeline.v1.GetTimelineResponse - 3, // 18: xyz.block.ftl.timeline.v1.TimelineService.CreateEvent:output_type -> xyz.block.ftl.timeline.v1.CreateEventResponse - 5, // 19: xyz.block.ftl.timeline.v1.TimelineService.DeleteOldEvents:output_type -> xyz.block.ftl.timeline.v1.DeleteOldEventsResponse - 16, // [16:20] is the sub-list for method output_type - 12, // [12:16] 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 + 16, // 0: xyz.block.ftl.timeline.v1.GetTimelineRequest.filters:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter + 0, // 1: xyz.block.ftl.timeline.v1.GetTimelineRequest.order:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.Order + 17, // 2: xyz.block.ftl.timeline.v1.GetTimelineResponse.events:type_name -> xyz.block.ftl.timeline.v1.Event + 18, // 3: xyz.block.ftl.timeline.v1.CreateEventRequest.log:type_name -> xyz.block.ftl.timeline.v1.LogEvent + 19, // 4: xyz.block.ftl.timeline.v1.CreateEventRequest.call:type_name -> xyz.block.ftl.timeline.v1.CallEvent + 20, // 5: xyz.block.ftl.timeline.v1.CreateEventRequest.deployment_created:type_name -> xyz.block.ftl.timeline.v1.DeploymentCreatedEvent + 21, // 6: xyz.block.ftl.timeline.v1.CreateEventRequest.deployment_updated:type_name -> xyz.block.ftl.timeline.v1.DeploymentUpdatedEvent + 22, // 7: xyz.block.ftl.timeline.v1.CreateEventRequest.ingress:type_name -> xyz.block.ftl.timeline.v1.IngressEvent + 23, // 8: xyz.block.ftl.timeline.v1.CreateEventRequest.cron_scheduled:type_name -> xyz.block.ftl.timeline.v1.CronScheduledEvent + 24, // 9: xyz.block.ftl.timeline.v1.CreateEventRequest.async_execute:type_name -> xyz.block.ftl.timeline.v1.AsyncExecuteEvent + 25, // 10: xyz.block.ftl.timeline.v1.CreateEventRequest.pubsub_publish:type_name -> xyz.block.ftl.timeline.v1.PubSubPublishEvent + 26, // 11: xyz.block.ftl.timeline.v1.CreateEventRequest.pubsub_consume:type_name -> xyz.block.ftl.timeline.v1.PubSubConsumeEvent + 27, // 12: xyz.block.ftl.timeline.v1.DeleteOldEventsRequest.event_type:type_name -> xyz.block.ftl.timeline.v1.EventType + 28, // 13: xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter.log_level:type_name -> xyz.block.ftl.timeline.v1.LogLevel + 27, // 14: xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter.event_types:type_name -> xyz.block.ftl.timeline.v1.EventType + 29, // 15: xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter.older_than:type_name -> google.protobuf.Timestamp + 29, // 16: xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter.newer_than:type_name -> google.protobuf.Timestamp + 7, // 17: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.limit:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilter + 8, // 18: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.log_level:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter + 9, // 19: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.deployments:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilter + 10, // 20: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.requests:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilter + 11, // 21: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.event_types:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter + 12, // 22: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.time:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter + 13, // 23: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.id:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilter + 14, // 24: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.call:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilter + 15, // 25: xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.module:type_name -> xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilter + 30, // 26: xyz.block.ftl.timeline.v1.TimelineService.Ping:input_type -> xyz.block.ftl.v1.PingRequest + 1, // 27: xyz.block.ftl.timeline.v1.TimelineService.GetTimeline:input_type -> xyz.block.ftl.timeline.v1.GetTimelineRequest + 3, // 28: xyz.block.ftl.timeline.v1.TimelineService.CreateEvent:input_type -> xyz.block.ftl.timeline.v1.CreateEventRequest + 5, // 29: xyz.block.ftl.timeline.v1.TimelineService.DeleteOldEvents:input_type -> xyz.block.ftl.timeline.v1.DeleteOldEventsRequest + 31, // 30: xyz.block.ftl.timeline.v1.TimelineService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 2, // 31: xyz.block.ftl.timeline.v1.TimelineService.GetTimeline:output_type -> xyz.block.ftl.timeline.v1.GetTimelineResponse + 4, // 32: xyz.block.ftl.timeline.v1.TimelineService.CreateEvent:output_type -> xyz.block.ftl.timeline.v1.CreateEventResponse + 6, // 33: xyz.block.ftl.timeline.v1.TimelineService.DeleteOldEvents:output_type -> xyz.block.ftl.timeline.v1.DeleteOldEventsResponse + 30, // [30:34] is the sub-list for method output_type + 26, // [26:30] is the sub-list for method input_type + 26, // [26:26] is the sub-list for extension type_name + 26, // [26:26] is the sub-list for extension extendee + 0, // [0:26] is the sub-list for field type_name } func init() { file_xyz_block_ftl_timeline_v1_timeline_proto_init() } @@ -642,7 +1455,6 @@ func file_xyz_block_ftl_timeline_v1_timeline_proto_init() { return } file_xyz_block_ftl_timeline_v1_event_proto_init() - file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[0].OneofWrappers = []any{} file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[2].OneofWrappers = []any{ (*CreateEventRequest_Log)(nil), (*CreateEventRequest_Call)(nil), @@ -654,18 +1466,34 @@ func file_xyz_block_ftl_timeline_v1_timeline_proto_init() { (*CreateEventRequest_PubsubPublish)(nil), (*CreateEventRequest_PubsubConsume)(nil), } + file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[11].OneofWrappers = []any{} + file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[12].OneofWrappers = []any{} + file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[13].OneofWrappers = []any{} + file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[14].OneofWrappers = []any{} + file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes[15].OneofWrappers = []any{ + (*GetTimelineRequest_Filter_Limit)(nil), + (*GetTimelineRequest_Filter_LogLevel)(nil), + (*GetTimelineRequest_Filter_Deployments)(nil), + (*GetTimelineRequest_Filter_Requests)(nil), + (*GetTimelineRequest_Filter_EventTypes)(nil), + (*GetTimelineRequest_Filter_Time)(nil), + (*GetTimelineRequest_Filter_Id)(nil), + (*GetTimelineRequest_Filter_Call)(nil), + (*GetTimelineRequest_Filter_Module)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_timeline_v1_timeline_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, + NumEnums: 1, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, GoTypes: file_xyz_block_ftl_timeline_v1_timeline_proto_goTypes, DependencyIndexes: file_xyz_block_ftl_timeline_v1_timeline_proto_depIdxs, + EnumInfos: file_xyz_block_ftl_timeline_v1_timeline_proto_enumTypes, MessageInfos: file_xyz_block_ftl_timeline_v1_timeline_proto_msgTypes, }.Build() File_xyz_block_ftl_timeline_v1_timeline_proto = out.File diff --git a/backend/protos/xyz/block/ftl/timeline/v1/timeline.proto b/backend/protos/xyz/block/ftl/timeline/v1/timeline.proto index 61bc4a70f2..c8a4eee8cf 100644 --- a/backend/protos/xyz/block/ftl/timeline/v1/timeline.proto +++ b/backend/protos/xyz/block/ftl/timeline/v1/timeline.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package xyz.block.ftl.timeline.v1; +import "google/protobuf/timestamp.proto"; import "xyz/block/ftl/timeline/v1/event.proto"; import "xyz/block/ftl/v1/ftl.proto"; @@ -9,10 +10,75 @@ option go_package = "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/tim option java_multiple_files = true; message GetTimelineRequest { - string deployment_key = 1; - optional int64 since_id = 2; - optional int32 limit = 3; - repeated timeline.v1.EventType event_types = 4; + // Limit the number of events returned. + message LimitFilter { + int32 limit = 1; + } + // Filters events by log level. + message LogLevelFilter { + timeline.v1.LogLevel log_level = 1; + } + // Filters events by deployment key. + message DeploymentFilter { + repeated string deployments = 1; + } + // Filters events by request key. + message RequestFilter { + repeated string requests = 1; + } + // Filters events by event type. + message EventTypeFilter { + repeated timeline.v1.EventType event_types = 1; + } + // Filters events by time. + // + // Either end of the time range can be omitted to indicate no bound. + message TimeFilter { + optional google.protobuf.Timestamp older_than = 1; + optional google.protobuf.Timestamp newer_than = 2; + } + // Filters events by ID. + // + // Either end of the ID range can be omitted to indicate no bound. + message IDFilter { + optional int64 lower_than = 1; + optional int64 higher_than = 2; + } + // Filters events by call. + message CallFilter { + string dest_module = 1; + optional string dest_verb = 2; + optional string source_module = 3; + } + message ModuleFilter { + string module = 1; + optional string verb = 2; + } + + enum Order { + ORDER_UNSPECIFIED = 0; + ORDER_ASC = 1; + ORDER_DESC = 2; + } + + message Filter { + // These map 1:1 with filters in backend/timeline/filters.go + oneof filter { + LimitFilter limit = 1; + LogLevelFilter log_level = 2; + DeploymentFilter deployments = 3; + RequestFilter requests = 4; + EventTypeFilter event_types = 5; + TimeFilter time = 6; + IDFilter id = 7; + CallFilter call = 8; + ModuleFilter module = 9; + } + } + + repeated Filter filters = 1; + int32 limit = 2; + Order order = 3; } message GetTimelineResponse { diff --git a/backend/timeline/events.go b/backend/timeline/events.go deleted file mode 100644 index eef1f6f605..0000000000 --- a/backend/timeline/events.go +++ /dev/null @@ -1,68 +0,0 @@ -package timeline - -import ( - "fmt" - "slices" - - timelinepb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/timeline/v1" -) - -func filter(event *timelinepb.Event, depKey string, eventTypes []timelinepb.EventType) bool { - if !slices.Contains(eventTypes, eventType(event)) { - return false - } - if depKey != "" && depKey != deploymentKey(event) { - return false - } - return true -} - -func eventType(event *timelinepb.Event) timelinepb.EventType { - switch event.Entry.(type) { - case *timelinepb.Event_Log: - return timelinepb.EventType_EVENT_TYPE_LOG - case *timelinepb.Event_Call: - return timelinepb.EventType_EVENT_TYPE_CALL - case *timelinepb.Event_DeploymentCreated: - return timelinepb.EventType_EVENT_TYPE_DEPLOYMENT_CREATED - case *timelinepb.Event_DeploymentUpdated: - return timelinepb.EventType_EVENT_TYPE_DEPLOYMENT_UPDATED - case *timelinepb.Event_Ingress: - return timelinepb.EventType_EVENT_TYPE_INGRESS - case *timelinepb.Event_CronScheduled: - return timelinepb.EventType_EVENT_TYPE_CRON_SCHEDULED - case *timelinepb.Event_AsyncExecute: - return timelinepb.EventType_EVENT_TYPE_ASYNC_EXECUTE - case *timelinepb.Event_PubsubPublish: - return timelinepb.EventType_EVENT_TYPE_PUBSUB_PUBLISH - case *timelinepb.Event_PubsubConsume: - return timelinepb.EventType_EVENT_TYPE_PUBSUB_CONSUME - default: - panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) - } -} - -func deploymentKey(event *timelinepb.Event) string { - switch entry := event.Entry.(type) { - case *timelinepb.Event_Log: - return entry.Log.DeploymentKey - case *timelinepb.Event_Call: - return entry.Call.DeploymentKey - case *timelinepb.Event_DeploymentCreated: - return entry.DeploymentCreated.Key - case *timelinepb.Event_DeploymentUpdated: - return entry.DeploymentUpdated.Key - case *timelinepb.Event_Ingress: - return entry.Ingress.DeploymentKey - case *timelinepb.Event_CronScheduled: - return entry.CronScheduled.DeploymentKey - case *timelinepb.Event_AsyncExecute: - return entry.AsyncExecute.DeploymentKey - case *timelinepb.Event_PubsubPublish: - return entry.PubsubPublish.DeploymentKey - case *timelinepb.Event_PubsubConsume: - return entry.PubsubConsume.DeploymentKey - default: - panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) - } -} diff --git a/backend/timeline/filters.go b/backend/timeline/filters.go new file mode 100644 index 0000000000..718215a02a --- /dev/null +++ b/backend/timeline/filters.go @@ -0,0 +1,272 @@ +package timeline + +import ( + "fmt" + "reflect" + "slices" + + "github.com/alecthomas/types/optional" + + timelinepb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/timeline/v1" + islices "github.com/TBD54566975/ftl/internal/slices" +) + +type TimelineFilter func(event *timelinepb.Event) bool + +func FilterLogLevel(f *timelinepb.GetTimelineRequest_LogLevelFilter) TimelineFilter { + return func(event *timelinepb.Event) bool { + log, ok := event.Entry.(*timelinepb.Event_Log) + if !ok { + // allow non-log events to pass through + return true + } + return int(log.Log.LogLevel) >= int(f.LogLevel) + } +} + +// FilterCall filters call events between the given modules. +// +// Takes a list of filters, with each call event needing to match at least one filter. +func FilterCall(filters []*timelinepb.GetTimelineRequest_CallFilter) TimelineFilter { + return func(event *timelinepb.Event) bool { + call, ok := event.Entry.(*timelinepb.Event_Call) + if !ok { + // Allow non-call events to pass through. + return true + } + // Allow event if any event filter matches. + _, ok = islices.Find(filters, func(f *timelinepb.GetTimelineRequest_CallFilter) bool { + if call.Call.DestinationVerbRef.Module != f.DestModule { + return false + } + if f.DestVerb != nil && call.Call.DestinationVerbRef.Name != *f.DestVerb { + return false + } + if f.SourceModule != nil && call.Call.SourceVerbRef.Module != *f.SourceModule { + return false + } + return true + }) + return ok + } +} + +func FilterModule(filters []*timelinepb.GetTimelineRequest_ModuleFilter) TimelineFilter { + return func(event *timelinepb.Event) bool { + var module, verb string + switch entry := event.Entry.(type) { + case *timelinepb.Event_Call: + module = entry.Call.DestinationVerbRef.Module + verb = entry.Call.DestinationVerbRef.Name + case *timelinepb.Event_Ingress: + module = entry.Ingress.VerbRef.Module + verb = entry.Ingress.VerbRef.Name + case *timelinepb.Event_AsyncExecute: + module = entry.AsyncExecute.VerbRef.Module + verb = entry.AsyncExecute.VerbRef.Name + case *timelinepb.Event_PubsubPublish: + module = entry.PubsubPublish.VerbRef.Module + verb = entry.PubsubPublish.VerbRef.Name + case *timelinepb.Event_PubsubConsume: + module = *entry.PubsubConsume.DestVerbModule + verb = *entry.PubsubConsume.DestVerbName + case *timelinepb.Event_Log, *timelinepb.Event_DeploymentCreated, *timelinepb.Event_DeploymentUpdated, *timelinepb.Event_CronScheduled: + // Block all other event types. + return false + default: + panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) + } + // Allow event if any module filter matches. + _, ok := islices.Find(filters, func(f *timelinepb.GetTimelineRequest_ModuleFilter) bool { + if f.Module != module { + return false + } + if f.Verb != nil && *f.Verb != verb { + return false + } + return true + }) + return ok + } +} + +func FilterDeployments(filters []*timelinepb.GetTimelineRequest_DeploymentFilter) TimelineFilter { + deployments := islices.Reduce(filters, []string{}, func(acc []string, f *timelinepb.GetTimelineRequest_DeploymentFilter) []string { + return append(acc, f.Deployments...) + }) + return func(event *timelinepb.Event) bool { + var deployment string + switch entry := event.Entry.(type) { + case *timelinepb.Event_Log: + deployment = entry.Log.DeploymentKey + case *timelinepb.Event_Call: + deployment = entry.Call.DeploymentKey + case *timelinepb.Event_DeploymentCreated: + deployment = entry.DeploymentCreated.Key + case *timelinepb.Event_DeploymentUpdated: + deployment = entry.DeploymentUpdated.Key + case *timelinepb.Event_Ingress: + deployment = entry.Ingress.DeploymentKey + case *timelinepb.Event_CronScheduled: + deployment = entry.CronScheduled.DeploymentKey + case *timelinepb.Event_AsyncExecute: + deployment = entry.AsyncExecute.DeploymentKey + case *timelinepb.Event_PubsubPublish: + deployment = entry.PubsubPublish.DeploymentKey + case *timelinepb.Event_PubsubConsume: + deployment = entry.PubsubConsume.DeploymentKey + default: + panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) + } + return slices.Contains(deployments, deployment) + } +} + +func FilterRequests(filters []*timelinepb.GetTimelineRequest_RequestFilter) TimelineFilter { + requests := islices.Reduce(filters, []string{}, func(acc []string, f *timelinepb.GetTimelineRequest_RequestFilter) []string { + return append(acc, f.Requests...) + }) + return func(event *timelinepb.Event) bool { + var request *string + switch entry := event.Entry.(type) { + case *timelinepb.Event_Log: + request = entry.Log.RequestKey + case *timelinepb.Event_Call: + request = entry.Call.RequestKey + case *timelinepb.Event_Ingress: + request = entry.Ingress.RequestKey + case *timelinepb.Event_AsyncExecute: + request = entry.AsyncExecute.RequestKey + case *timelinepb.Event_PubsubPublish: + request = entry.PubsubPublish.RequestKey + case *timelinepb.Event_PubsubConsume: + request = entry.PubsubConsume.RequestKey + case *timelinepb.Event_DeploymentCreated, *timelinepb.Event_DeploymentUpdated, *timelinepb.Event_CronScheduled: + default: + panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) + } + if request == nil { + return false + } + return slices.Contains(requests, *request) + } +} + +func FilterTypes(filters ...*timelinepb.GetTimelineRequest_EventTypeFilter) TimelineFilter { + types := islices.Reduce(filters, []timelinepb.EventType{}, func(acc []timelinepb.EventType, f *timelinepb.GetTimelineRequest_EventTypeFilter) []timelinepb.EventType { + return append(acc, f.EventTypes...) + }) + allowsAll := slices.Contains(types, timelinepb.EventType_EVENT_TYPE_UNSPECIFIED) + return func(event *timelinepb.Event) bool { + if allowsAll { + return true + } + var eventType timelinepb.EventType + switch event.Entry.(type) { + case *timelinepb.Event_Log: + eventType = timelinepb.EventType_EVENT_TYPE_LOG + case *timelinepb.Event_Call: + eventType = timelinepb.EventType_EVENT_TYPE_CALL + case *timelinepb.Event_DeploymentCreated: + eventType = timelinepb.EventType_EVENT_TYPE_DEPLOYMENT_CREATED + case *timelinepb.Event_DeploymentUpdated: + eventType = timelinepb.EventType_EVENT_TYPE_DEPLOYMENT_UPDATED + case *timelinepb.Event_Ingress: + eventType = timelinepb.EventType_EVENT_TYPE_INGRESS + case *timelinepb.Event_CronScheduled: + eventType = timelinepb.EventType_EVENT_TYPE_CRON_SCHEDULED + case *timelinepb.Event_AsyncExecute: + eventType = timelinepb.EventType_EVENT_TYPE_ASYNC_EXECUTE + case *timelinepb.Event_PubsubPublish: + eventType = timelinepb.EventType_EVENT_TYPE_PUBSUB_PUBLISH + case *timelinepb.Event_PubsubConsume: + eventType = timelinepb.EventType_EVENT_TYPE_PUBSUB_CONSUME + default: + panic(fmt.Sprintf("unexpected event type: %T", event.Entry)) + } + return slices.Contains(types, eventType) + } +} + +// FilterTimeRange filters events between the given times, inclusive. +func FilterTimeRange(filter *timelinepb.GetTimelineRequest_TimeFilter) TimelineFilter { + return func(event *timelinepb.Event) bool { + if filter.NewerThan != nil && event.TimeStamp.AsTime().Before(filter.NewerThan.AsTime()) { + return false + } + if filter.OlderThan != nil && event.TimeStamp.AsTime().After(filter.OlderThan.AsTime()) { + return false + } + return true + } +} + +// FilterIDRange filters events between the given IDs, inclusive. +func FilterIDRange(filter *timelinepb.GetTimelineRequest_IDFilter) TimelineFilter { + return func(event *timelinepb.Event) bool { + if filter.HigherThan != nil && event.Id < *filter.HigherThan { + return false + } + if filter.LowerThan != nil && event.Id > *filter.LowerThan { + return false + } + return true + } +} + +//nolint:maintidx +func filtersFromRequest(req *timelinepb.GetTimelineRequest) (outFilters []TimelineFilter, limit optional.Option[int], ascending bool, err error) { + if req.Order != timelinepb.GetTimelineRequest_ORDER_DESC { + ascending = true + } + + // Some filters need to be combined (for OR logic), so we group them by type first. + reqFiltersByType := map[reflect.Type][]*timelinepb.GetTimelineRequest_Filter{} + for _, filter := range req.Filters { + reqFiltersByType[reflect.TypeOf(filter.Filter)] = append(reqFiltersByType[reflect.TypeOf(filter.Filter)], filter) + } + for _, filters := range reqFiltersByType { + switch filters[0].Filter.(type) { + case *timelinepb.GetTimelineRequest_Filter_Limit: + if len(filters) > 1 { + return nil, optional.None[int](), false, fmt.Errorf("multiple limit filters not supported") + } + limit = optional.Some(int(filters[0].GetLimit().Limit)) + case *timelinepb.GetTimelineRequest_Filter_LogLevel: + outFilters = append(outFilters, islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) TimelineFilter { + return FilterLogLevel(f.GetLogLevel()) + })...) + case *timelinepb.GetTimelineRequest_Filter_Deployments: + outFilters = append(outFilters, FilterDeployments(islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) *timelinepb.GetTimelineRequest_DeploymentFilter { + return f.GetDeployments() + }))) + case *timelinepb.GetTimelineRequest_Filter_Requests: + outFilters = append(outFilters, FilterRequests(islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) *timelinepb.GetTimelineRequest_RequestFilter { + return f.GetRequests() + }))) + case *timelinepb.GetTimelineRequest_Filter_EventTypes: + outFilters = append(outFilters, FilterTypes(islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) *timelinepb.GetTimelineRequest_EventTypeFilter { + return f.GetEventTypes() + })...)) + case *timelinepb.GetTimelineRequest_Filter_Time: + outFilters = append(outFilters, islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) TimelineFilter { + return FilterTimeRange(f.GetTime()) + })...) + case *timelinepb.GetTimelineRequest_Filter_Id: + outFilters = append(outFilters, islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) TimelineFilter { + return FilterIDRange(f.GetId()) + })...) + case *timelinepb.GetTimelineRequest_Filter_Call: + outFilters = append(outFilters, FilterCall(islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) *timelinepb.GetTimelineRequest_CallFilter { + return f.GetCall() + }))) + case *timelinepb.GetTimelineRequest_Filter_Module: + outFilters = append(outFilters, FilterModule(islices.Map(filters, func(f *timelinepb.GetTimelineRequest_Filter) *timelinepb.GetTimelineRequest_ModuleFilter { + return f.GetModule() + }))) + default: + panic(fmt.Sprintf("unexpected filter type: %T", filters[0].Filter)) + } + } + return outFilters, limit, ascending, nil +} diff --git a/backend/timeline/service.go b/backend/timeline/service.go index 665b13db6f..5be3cf4814 100644 --- a/backend/timeline/service.go +++ b/backend/timeline/service.go @@ -17,6 +17,7 @@ import ( "github.com/TBD54566975/ftl/internal/log" "github.com/TBD54566975/ftl/internal/rpc" "github.com/TBD54566975/ftl/internal/schema/schemaeventsource" + "github.com/TBD54566975/ftl/internal/slices" ) type Config struct { @@ -110,15 +111,34 @@ func (s *service) GetTimeline(ctx context.Context, req *connect.Request[timeline s.lock.RLock() defer s.lock.RUnlock() + filters, limit, ascending, err := filtersFromRequest(req.Msg) + if err != nil { + return nil, err + } + results := []*timelinepb.Event{} - // TODO: handle sinceId - for i := len(s.events) - 1; i >= 0; i-- { + + var firstIdx, step int + var idxCheck func(int) bool + if ascending { + firstIdx = 0 + step = 1 + idxCheck = func(i int) bool { return i < len(s.events) } + } else { + firstIdx = len(s.events) - 1 + step = -1 + idxCheck = func(i int) bool { return i >= 0 } + } + for i := firstIdx; idxCheck(i); i += step { event := s.events[i] - if !filter(event, req.Msg.DeploymentKey, req.Msg.EventTypes) { + _, didNotMatchAFilter := slices.Find(filters, func(filter TimelineFilter) bool { + return !filter(event) + }) + for didNotMatchAFilter { continue } results = append(results, s.events[i]) - if req.Msg.Limit != nil && *req.Msg.Limit != 0 && len(results) >= int(*req.Msg.Limit) { + if limit, ok := limit.Get(); ok && limit != 0 && len(results) >= limit { break } } @@ -130,14 +150,25 @@ func (s *service) GetTimeline(ctx context.Context, req *connect.Request[timeline func (s *service) DeleteOldEvents(ctx context.Context, req *connect.Request[timelinepb.DeleteOldEventsRequest]) (*connect.Response[timelinepb.DeleteOldEventsResponse], error) { s.lock.Lock() defer s.lock.Unlock() - + // Events that match all these filters will be deleted cutoff := time.Now().Add(-1 * time.Duration(req.Msg.AgeSeconds) * time.Second) + deletionFilters := []TimelineFilter{ + FilterTypes(&timelinepb.GetTimelineRequest_EventTypeFilter{ + EventTypes: []timelinepb.EventType{req.Msg.EventType}, + }), + FilterTimeRange(&timelinepb.GetTimelineRequest_TimeFilter{ + OlderThan: timestamppb.New(cutoff), + }), + } + filtered := []*timelinepb.Event{} for _, event := range s.events { - if event.TimeStamp.AsTime().Before(cutoff) && (req.Msg.EventType == timelinepb.EventType_EVENT_TYPE_UNSPECIFIED || req.Msg.EventType != eventType(event)) { - continue + _, didNotMatchAFilter := slices.Find(deletionFilters, func(filter TimelineFilter) bool { + return !filter(event) + }) + if didNotMatchAFilter { + filtered = append(filtered, event) } - filtered = append(filtered, event) } s.events = filtered return connect.NewResponse(&timelinepb.DeleteOldEventsResponse{}), nil diff --git a/backend/timeline/service_test.go b/backend/timeline/service_test.go index e438c3a02f..218c57e2b4 100644 --- a/backend/timeline/service_test.go +++ b/backend/timeline/service_test.go @@ -42,9 +42,24 @@ func TestGetTimelineWithLimit(t *testing.T) { 110, } { resp, err := service.GetTimeline(ctx, connect.NewRequest(&timelinepb.GetTimelineRequest{ - Limit: &limit, - EventTypes: []timelinepb.EventType{ - timelinepb.EventType_EVENT_TYPE_CALL, + Order: timelinepb.GetTimelineRequest_ORDER_DESC, + Filters: []*timelinepb.GetTimelineRequest_Filter{ + { + Filter: &timelinepb.GetTimelineRequest_Filter_EventTypes{ + EventTypes: &timelinepb.GetTimelineRequest_EventTypeFilter{ + EventTypes: []timelinepb.EventType{ + timelinepb.EventType_EVENT_TYPE_CALL, + }, + }, + }, + }, + { + Filter: &timelinepb.GetTimelineRequest_Filter_Limit{ + Limit: &timelinepb.GetTimelineRequest_LimitFilter{ + Limit: limit, + }, + }, + }, }, })) assert.NoError(t, err) diff --git a/frontend/console/src/protos/xyz/block/ftl/timeline/v1/timeline_pb.ts b/frontend/console/src/protos/xyz/block/ftl/timeline/v1/timeline_pb.ts index 1c6f0a4ec4..e01cce29c7 100644 --- a/frontend/console/src/protos/xyz/block/ftl/timeline/v1/timeline_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/timeline/v1/timeline_pb.ts @@ -4,32 +4,27 @@ // @ts-nocheck import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; -import { Message, proto3, protoInt64 } from "@bufbuild/protobuf"; -import { AsyncExecuteEvent, CallEvent, CronScheduledEvent, DeploymentCreatedEvent, DeploymentUpdatedEvent, Event, EventType, IngressEvent, LogEvent, PubSubConsumeEvent, PubSubPublishEvent } from "./event_pb.js"; +import { Message, proto3, protoInt64, Timestamp } from "@bufbuild/protobuf"; +import { AsyncExecuteEvent, CallEvent, CronScheduledEvent, DeploymentCreatedEvent, DeploymentUpdatedEvent, Event, EventType, IngressEvent, LogEvent, LogLevel, PubSubConsumeEvent, PubSubPublishEvent } from "./event_pb.js"; /** * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest */ export class GetTimelineRequest extends Message { /** - * @generated from field: string deployment_key = 1; + * @generated from field: repeated xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter filters = 1; */ - deploymentKey = ""; + filters: GetTimelineRequest_Filter[] = []; /** - * @generated from field: optional int64 since_id = 2; + * @generated from field: int32 limit = 2; */ - sinceId?: bigint; + limit = 0; /** - * @generated from field: optional int32 limit = 3; + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.Order order = 3; */ - limit?: number; - - /** - * @generated from field: repeated xyz.block.ftl.timeline.v1.EventType event_types = 4; - */ - eventTypes: EventType[] = []; + order = GetTimelineRequest_Order.UNSPECIFIED; constructor(data?: PartialMessage) { super(); @@ -39,10 +34,9 @@ export class GetTimelineRequest extends Message { static readonly runtime: typeof proto3 = proto3; static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest"; static readonly fields: FieldList = proto3.util.newFieldList(() => [ - { no: 1, name: "deployment_key", kind: "scalar", T: 9 /* ScalarType.STRING */ }, - { no: 2, name: "since_id", kind: "scalar", T: 3 /* ScalarType.INT64 */, opt: true }, - { no: 3, name: "limit", kind: "scalar", T: 5 /* ScalarType.INT32 */, opt: true }, - { no: 4, name: "event_types", kind: "enum", T: proto3.getEnumType(EventType), repeated: true }, + { no: 1, name: "filters", kind: "message", T: GetTimelineRequest_Filter, repeated: true }, + { no: 2, name: "limit", kind: "scalar", T: 5 /* ScalarType.INT32 */ }, + { no: 3, name: "order", kind: "enum", T: proto3.getEnumType(GetTimelineRequest_Order) }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest { @@ -62,6 +56,516 @@ export class GetTimelineRequest extends Message { } } +/** + * @generated from enum xyz.block.ftl.timeline.v1.GetTimelineRequest.Order + */ +export enum GetTimelineRequest_Order { + /** + * @generated from enum value: ORDER_UNSPECIFIED = 0; + */ + UNSPECIFIED = 0, + + /** + * @generated from enum value: ORDER_ASC = 1; + */ + ASC = 1, + + /** + * @generated from enum value: ORDER_DESC = 2; + */ + DESC = 2, +} +// Retrieve enum metadata with: proto3.getEnumType(GetTimelineRequest_Order) +proto3.util.setEnumType(GetTimelineRequest_Order, "xyz.block.ftl.timeline.v1.GetTimelineRequest.Order", [ + { no: 0, name: "ORDER_UNSPECIFIED" }, + { no: 1, name: "ORDER_ASC" }, + { no: 2, name: "ORDER_DESC" }, +]); + +/** + * Limit the number of events returned. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilter + */ +export class GetTimelineRequest_LimitFilter extends Message { + /** + * @generated from field: int32 limit = 1; + */ + limit = 0; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "limit", kind: "scalar", T: 5 /* ScalarType.INT32 */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_LimitFilter { + return new GetTimelineRequest_LimitFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_LimitFilter { + return new GetTimelineRequest_LimitFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_LimitFilter { + return new GetTimelineRequest_LimitFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_LimitFilter | PlainMessage | undefined, b: GetTimelineRequest_LimitFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_LimitFilter, a, b); + } +} + +/** + * Filters events by log level. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter + */ +export class GetTimelineRequest_LogLevelFilter extends Message { + /** + * @generated from field: xyz.block.ftl.timeline.v1.LogLevel log_level = 1; + */ + logLevel = LogLevel.UNSPECIFIED; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "log_level", kind: "enum", T: proto3.getEnumType(LogLevel) }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_LogLevelFilter { + return new GetTimelineRequest_LogLevelFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_LogLevelFilter { + return new GetTimelineRequest_LogLevelFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_LogLevelFilter { + return new GetTimelineRequest_LogLevelFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_LogLevelFilter | PlainMessage | undefined, b: GetTimelineRequest_LogLevelFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_LogLevelFilter, a, b); + } +} + +/** + * Filters events by deployment key. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilter + */ +export class GetTimelineRequest_DeploymentFilter extends Message { + /** + * @generated from field: repeated string deployments = 1; + */ + deployments: string[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "deployments", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_DeploymentFilter { + return new GetTimelineRequest_DeploymentFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_DeploymentFilter { + return new GetTimelineRequest_DeploymentFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_DeploymentFilter { + return new GetTimelineRequest_DeploymentFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_DeploymentFilter | PlainMessage | undefined, b: GetTimelineRequest_DeploymentFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_DeploymentFilter, a, b); + } +} + +/** + * Filters events by request key. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilter + */ +export class GetTimelineRequest_RequestFilter extends Message { + /** + * @generated from field: repeated string requests = 1; + */ + requests: string[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "requests", kind: "scalar", T: 9 /* ScalarType.STRING */, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_RequestFilter { + return new GetTimelineRequest_RequestFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_RequestFilter { + return new GetTimelineRequest_RequestFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_RequestFilter { + return new GetTimelineRequest_RequestFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_RequestFilter | PlainMessage | undefined, b: GetTimelineRequest_RequestFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_RequestFilter, a, b); + } +} + +/** + * Filters events by event type. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter + */ +export class GetTimelineRequest_EventTypeFilter extends Message { + /** + * @generated from field: repeated xyz.block.ftl.timeline.v1.EventType event_types = 1; + */ + eventTypes: EventType[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "event_types", kind: "enum", T: proto3.getEnumType(EventType), repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_EventTypeFilter { + return new GetTimelineRequest_EventTypeFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_EventTypeFilter { + return new GetTimelineRequest_EventTypeFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_EventTypeFilter { + return new GetTimelineRequest_EventTypeFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_EventTypeFilter | PlainMessage | undefined, b: GetTimelineRequest_EventTypeFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_EventTypeFilter, a, b); + } +} + +/** + * Filters events by time. + * + * Either end of the time range can be omitted to indicate no bound. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter + */ +export class GetTimelineRequest_TimeFilter extends Message { + /** + * @generated from field: optional google.protobuf.Timestamp older_than = 1; + */ + olderThan?: Timestamp; + + /** + * @generated from field: optional google.protobuf.Timestamp newer_than = 2; + */ + newerThan?: Timestamp; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "older_than", kind: "message", T: Timestamp, opt: true }, + { no: 2, name: "newer_than", kind: "message", T: Timestamp, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_TimeFilter { + return new GetTimelineRequest_TimeFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_TimeFilter { + return new GetTimelineRequest_TimeFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_TimeFilter { + return new GetTimelineRequest_TimeFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_TimeFilter | PlainMessage | undefined, b: GetTimelineRequest_TimeFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_TimeFilter, a, b); + } +} + +/** + * Filters events by ID. + * + * Either end of the ID range can be omitted to indicate no bound. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilter + */ +export class GetTimelineRequest_IDFilter extends Message { + /** + * @generated from field: optional int64 lower_than = 1; + */ + lowerThan?: bigint; + + /** + * @generated from field: optional int64 higher_than = 2; + */ + higherThan?: bigint; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "lower_than", kind: "scalar", T: 3 /* ScalarType.INT64 */, opt: true }, + { no: 2, name: "higher_than", kind: "scalar", T: 3 /* ScalarType.INT64 */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_IDFilter { + return new GetTimelineRequest_IDFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_IDFilter { + return new GetTimelineRequest_IDFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_IDFilter { + return new GetTimelineRequest_IDFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_IDFilter | PlainMessage | undefined, b: GetTimelineRequest_IDFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_IDFilter, a, b); + } +} + +/** + * Filters events by call. + * + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilter + */ +export class GetTimelineRequest_CallFilter extends Message { + /** + * @generated from field: string dest_module = 1; + */ + destModule = ""; + + /** + * @generated from field: optional string dest_verb = 2; + */ + destVerb?: string; + + /** + * @generated from field: optional string source_module = 3; + */ + sourceModule?: string; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "dest_module", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "dest_verb", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 3, name: "source_module", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_CallFilter { + return new GetTimelineRequest_CallFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_CallFilter { + return new GetTimelineRequest_CallFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_CallFilter { + return new GetTimelineRequest_CallFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_CallFilter | PlainMessage | undefined, b: GetTimelineRequest_CallFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_CallFilter, a, b); + } +} + +/** + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilter + */ +export class GetTimelineRequest_ModuleFilter extends Message { + /** + * @generated from field: string module = 1; + */ + module = ""; + + /** + * @generated from field: optional string verb = 2; + */ + verb?: string; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "module", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "verb", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_ModuleFilter { + return new GetTimelineRequest_ModuleFilter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_ModuleFilter { + return new GetTimelineRequest_ModuleFilter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_ModuleFilter { + return new GetTimelineRequest_ModuleFilter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_ModuleFilter | PlainMessage | undefined, b: GetTimelineRequest_ModuleFilter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_ModuleFilter, a, b); + } +} + +/** + * @generated from message xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter + */ +export class GetTimelineRequest_Filter extends Message { + /** + * These map 1:1 with filters in backend/timeline/filters.go + * + * @generated from oneof xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter.filter + */ + filter: { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilter limit = 1; + */ + value: GetTimelineRequest_LimitFilter; + case: "limit"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilter log_level = 2; + */ + value: GetTimelineRequest_LogLevelFilter; + case: "logLevel"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilter deployments = 3; + */ + value: GetTimelineRequest_DeploymentFilter; + case: "deployments"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilter requests = 4; + */ + value: GetTimelineRequest_RequestFilter; + case: "requests"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilter event_types = 5; + */ + value: GetTimelineRequest_EventTypeFilter; + case: "eventTypes"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilter time = 6; + */ + value: GetTimelineRequest_TimeFilter; + case: "time"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilter id = 7; + */ + value: GetTimelineRequest_IDFilter; + case: "id"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilter call = 8; + */ + value: GetTimelineRequest_CallFilter; + case: "call"; + } | { + /** + * @generated from field: xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilter module = 9; + */ + value: GetTimelineRequest_ModuleFilter; + case: "module"; + } | { case: undefined; value?: undefined } = { case: undefined }; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.timeline.v1.GetTimelineRequest.Filter"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "limit", kind: "message", T: GetTimelineRequest_LimitFilter, oneof: "filter" }, + { no: 2, name: "log_level", kind: "message", T: GetTimelineRequest_LogLevelFilter, oneof: "filter" }, + { no: 3, name: "deployments", kind: "message", T: GetTimelineRequest_DeploymentFilter, oneof: "filter" }, + { no: 4, name: "requests", kind: "message", T: GetTimelineRequest_RequestFilter, oneof: "filter" }, + { no: 5, name: "event_types", kind: "message", T: GetTimelineRequest_EventTypeFilter, oneof: "filter" }, + { no: 6, name: "time", kind: "message", T: GetTimelineRequest_TimeFilter, oneof: "filter" }, + { no: 7, name: "id", kind: "message", T: GetTimelineRequest_IDFilter, oneof: "filter" }, + { no: 8, name: "call", kind: "message", T: GetTimelineRequest_CallFilter, oneof: "filter" }, + { no: 9, name: "module", kind: "message", T: GetTimelineRequest_ModuleFilter, oneof: "filter" }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GetTimelineRequest_Filter { + return new GetTimelineRequest_Filter().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GetTimelineRequest_Filter { + return new GetTimelineRequest_Filter().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GetTimelineRequest_Filter { + return new GetTimelineRequest_Filter().fromJsonString(jsonString, options); + } + + static equals(a: GetTimelineRequest_Filter | PlainMessage | undefined, b: GetTimelineRequest_Filter | PlainMessage | undefined): boolean { + return proto3.util.equals(GetTimelineRequest_Filter, a, b); + } +} + /** * @generated from message xyz.block.ftl.timeline.v1.GetTimelineResponse */ diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.py index fb22a630bc..1ea2e1fee6 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.py @@ -22,11 +22,12 @@ _sym_db = _symbol_database.Default() +from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 from xyz.block.ftl.timeline.v1 import event_pb2 as xyz_dot_block_dot_ftl_dot_timeline_dot_v1_dot_event__pb2 from xyz.block.ftl.v1 import ftl_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_ftl__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(xyz/block/ftl/timeline/v1/timeline.proto\x12\x19xyz.block.ftl.timeline.v1\x1a%xyz/block/ftl/timeline/v1/event.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"\xd4\x01\n\x12GetTimelineRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x1e\n\x08since_id\x18\x02 \x01(\x03H\x00R\x07sinceId\x88\x01\x01\x12\x19\n\x05limit\x18\x03 \x01(\x05H\x01R\x05limit\x88\x01\x01\x12\x45\n\x0b\x65vent_types\x18\x04 \x03(\x0e\x32$.xyz.block.ftl.timeline.v1.EventTypeR\neventTypesB\x0b\n\t_since_idB\x08\n\x06_limit\"O\n\x13GetTimelineResponse\x12\x38\n\x06\x65vents\x18\x01 \x03(\x0b\x32 .xyz.block.ftl.timeline.v1.EventR\x06\x65vents\"\xfc\x05\n\x12\x43reateEventRequest\x12\x37\n\x03log\x18\x01 \x01(\x0b\x32#.xyz.block.ftl.timeline.v1.LogEventH\x00R\x03log\x12:\n\x04\x63\x61ll\x18\x02 \x01(\x0b\x32$.xyz.block.ftl.timeline.v1.CallEventH\x00R\x04\x63\x61ll\x12\x62\n\x12\x64\x65ployment_created\x18\x03 \x01(\x0b\x32\x31.xyz.block.ftl.timeline.v1.DeploymentCreatedEventH\x00R\x11\x64\x65ploymentCreated\x12\x62\n\x12\x64\x65ployment_updated\x18\x04 \x01(\x0b\x32\x31.xyz.block.ftl.timeline.v1.DeploymentUpdatedEventH\x00R\x11\x64\x65ploymentUpdated\x12\x43\n\x07ingress\x18\x05 \x01(\x0b\x32\'.xyz.block.ftl.timeline.v1.IngressEventH\x00R\x07ingress\x12V\n\x0e\x63ron_scheduled\x18\x06 \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.CronScheduledEventH\x00R\rcronScheduled\x12S\n\rasync_execute\x18\x07 \x01(\x0b\x32,.xyz.block.ftl.timeline.v1.AsyncExecuteEventH\x00R\x0c\x61syncExecute\x12V\n\x0epubsub_publish\x18\x08 \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.PubSubPublishEventH\x00R\rpubsubPublish\x12V\n\x0epubsub_consume\x18\t \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.PubSubConsumeEventH\x00R\rpubsubConsumeB\x07\n\x05\x65ntry\"\x15\n\x13\x43reateEventResponse\"~\n\x16\x44\x65leteOldEventsRequest\x12\x43\n\nevent_type\x18\x01 \x01(\x0e\x32$.xyz.block.ftl.timeline.v1.EventTypeR\teventType\x12\x1f\n\x0b\x61ge_seconds\x18\x02 \x01(\x03R\nageSeconds\">\n\x17\x44\x65leteOldEventsResponse\x12#\n\rdeleted_count\x18\x01 \x01(\x03R\x0c\x64\x65letedCount2\xbc\x03\n\x0fTimelineService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12q\n\x0bGetTimeline\x12-.xyz.block.ftl.timeline.v1.GetTimelineRequest\x1a..xyz.block.ftl.timeline.v1.GetTimelineResponse\"\x03\x90\x02\x01\x12n\n\x0b\x43reateEvent\x12-.xyz.block.ftl.timeline.v1.CreateEventRequest\x1a..xyz.block.ftl.timeline.v1.CreateEventResponse\"\x00\x12z\n\x0f\x44\x65leteOldEvents\x12\x31.xyz.block.ftl.timeline.v1.DeleteOldEventsRequest\x1a\x32.xyz.block.ftl.timeline.v1.DeleteOldEventsResponse\"\x00\x42RP\x01ZNgithub.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/timeline/v1;timelinev1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(xyz/block/ftl/timeline/v1/timeline.proto\x12\x19xyz.block.ftl.timeline.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a%xyz/block/ftl/timeline/v1/event.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"\xe8\x0e\n\x12GetTimelineRequest\x12N\n\x07\x66ilters\x18\x01 \x03(\x0b\x32\x34.xyz.block.ftl.timeline.v1.GetTimelineRequest.FilterR\x07\x66ilters\x12\x14\n\x05limit\x18\x02 \x01(\x05R\x05limit\x12I\n\x05order\x18\x03 \x01(\x0e\x32\x33.xyz.block.ftl.timeline.v1.GetTimelineRequest.OrderR\x05order\x1a#\n\x0bLimitFilter\x12\x14\n\x05limit\x18\x01 \x01(\x05R\x05limit\x1aR\n\x0eLogLevelFilter\x12@\n\tlog_level\x18\x01 \x01(\x0e\x32#.xyz.block.ftl.timeline.v1.LogLevelR\x08logLevel\x1a\x34\n\x10\x44\x65ploymentFilter\x12 \n\x0b\x64\x65ployments\x18\x01 \x03(\tR\x0b\x64\x65ployments\x1a+\n\rRequestFilter\x12\x1a\n\x08requests\x18\x01 \x03(\tR\x08requests\x1aX\n\x0f\x45ventTypeFilter\x12\x45\n\x0b\x65vent_types\x18\x01 \x03(\x0e\x32$.xyz.block.ftl.timeline.v1.EventTypeR\neventTypes\x1a\xaa\x01\n\nTimeFilter\x12>\n\nolder_than\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00R\tolderThan\x88\x01\x01\x12>\n\nnewer_than\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x01R\tnewerThan\x88\x01\x01\x42\r\n\x0b_older_thanB\r\n\x0b_newer_than\x1as\n\x08IDFilter\x12\"\n\nlower_than\x18\x01 \x01(\x03H\x00R\tlowerThan\x88\x01\x01\x12$\n\x0bhigher_than\x18\x02 \x01(\x03H\x01R\nhigherThan\x88\x01\x01\x42\r\n\x0b_lower_thanB\x0e\n\x0c_higher_than\x1a\x99\x01\n\nCallFilter\x12\x1f\n\x0b\x64\x65st_module\x18\x01 \x01(\tR\ndestModule\x12 \n\tdest_verb\x18\x02 \x01(\tH\x00R\x08\x64\x65stVerb\x88\x01\x01\x12(\n\rsource_module\x18\x03 \x01(\tH\x01R\x0csourceModule\x88\x01\x01\x42\x0c\n\n_dest_verbB\x10\n\x0e_source_module\x1aH\n\x0cModuleFilter\x12\x16\n\x06module\x18\x01 \x01(\tR\x06module\x12\x17\n\x04verb\x18\x02 \x01(\tH\x00R\x04verb\x88\x01\x01\x42\x07\n\x05_verb\x1a\xa3\x06\n\x06\x46ilter\x12Q\n\x05limit\x18\x01 \x01(\x0b\x32\x39.xyz.block.ftl.timeline.v1.GetTimelineRequest.LimitFilterH\x00R\x05limit\x12[\n\tlog_level\x18\x02 \x01(\x0b\x32<.xyz.block.ftl.timeline.v1.GetTimelineRequest.LogLevelFilterH\x00R\x08logLevel\x12\x62\n\x0b\x64\x65ployments\x18\x03 \x01(\x0b\x32>.xyz.block.ftl.timeline.v1.GetTimelineRequest.DeploymentFilterH\x00R\x0b\x64\x65ployments\x12Y\n\x08requests\x18\x04 \x01(\x0b\x32;.xyz.block.ftl.timeline.v1.GetTimelineRequest.RequestFilterH\x00R\x08requests\x12`\n\x0b\x65vent_types\x18\x05 \x01(\x0b\x32=.xyz.block.ftl.timeline.v1.GetTimelineRequest.EventTypeFilterH\x00R\neventTypes\x12N\n\x04time\x18\x06 \x01(\x0b\x32\x38.xyz.block.ftl.timeline.v1.GetTimelineRequest.TimeFilterH\x00R\x04time\x12H\n\x02id\x18\x07 \x01(\x0b\x32\x36.xyz.block.ftl.timeline.v1.GetTimelineRequest.IDFilterH\x00R\x02id\x12N\n\x04\x63\x61ll\x18\x08 \x01(\x0b\x32\x38.xyz.block.ftl.timeline.v1.GetTimelineRequest.CallFilterH\x00R\x04\x63\x61ll\x12T\n\x06module\x18\t \x01(\x0b\x32:.xyz.block.ftl.timeline.v1.GetTimelineRequest.ModuleFilterH\x00R\x06moduleB\x08\n\x06\x66ilter\"=\n\x05Order\x12\x15\n\x11ORDER_UNSPECIFIED\x10\x00\x12\r\n\tORDER_ASC\x10\x01\x12\x0e\n\nORDER_DESC\x10\x02\"O\n\x13GetTimelineResponse\x12\x38\n\x06\x65vents\x18\x01 \x03(\x0b\x32 .xyz.block.ftl.timeline.v1.EventR\x06\x65vents\"\xfc\x05\n\x12\x43reateEventRequest\x12\x37\n\x03log\x18\x01 \x01(\x0b\x32#.xyz.block.ftl.timeline.v1.LogEventH\x00R\x03log\x12:\n\x04\x63\x61ll\x18\x02 \x01(\x0b\x32$.xyz.block.ftl.timeline.v1.CallEventH\x00R\x04\x63\x61ll\x12\x62\n\x12\x64\x65ployment_created\x18\x03 \x01(\x0b\x32\x31.xyz.block.ftl.timeline.v1.DeploymentCreatedEventH\x00R\x11\x64\x65ploymentCreated\x12\x62\n\x12\x64\x65ployment_updated\x18\x04 \x01(\x0b\x32\x31.xyz.block.ftl.timeline.v1.DeploymentUpdatedEventH\x00R\x11\x64\x65ploymentUpdated\x12\x43\n\x07ingress\x18\x05 \x01(\x0b\x32\'.xyz.block.ftl.timeline.v1.IngressEventH\x00R\x07ingress\x12V\n\x0e\x63ron_scheduled\x18\x06 \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.CronScheduledEventH\x00R\rcronScheduled\x12S\n\rasync_execute\x18\x07 \x01(\x0b\x32,.xyz.block.ftl.timeline.v1.AsyncExecuteEventH\x00R\x0c\x61syncExecute\x12V\n\x0epubsub_publish\x18\x08 \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.PubSubPublishEventH\x00R\rpubsubPublish\x12V\n\x0epubsub_consume\x18\t \x01(\x0b\x32-.xyz.block.ftl.timeline.v1.PubSubConsumeEventH\x00R\rpubsubConsumeB\x07\n\x05\x65ntry\"\x15\n\x13\x43reateEventResponse\"~\n\x16\x44\x65leteOldEventsRequest\x12\x43\n\nevent_type\x18\x01 \x01(\x0e\x32$.xyz.block.ftl.timeline.v1.EventTypeR\teventType\x12\x1f\n\x0b\x61ge_seconds\x18\x02 \x01(\x03R\nageSeconds\">\n\x17\x44\x65leteOldEventsResponse\x12#\n\rdeleted_count\x18\x01 \x01(\x03R\x0c\x64\x65letedCount2\xbc\x03\n\x0fTimelineService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12q\n\x0bGetTimeline\x12-.xyz.block.ftl.timeline.v1.GetTimelineRequest\x1a..xyz.block.ftl.timeline.v1.GetTimelineResponse\"\x03\x90\x02\x01\x12n\n\x0b\x43reateEvent\x12-.xyz.block.ftl.timeline.v1.CreateEventRequest\x1a..xyz.block.ftl.timeline.v1.CreateEventResponse\"\x00\x12z\n\x0f\x44\x65leteOldEvents\x12\x31.xyz.block.ftl.timeline.v1.DeleteOldEventsRequest\x1a\x32.xyz.block.ftl.timeline.v1.DeleteOldEventsResponse\"\x00\x42RP\x01ZNgithub.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/timeline/v1;timelinev1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -38,18 +39,40 @@ _globals['_TIMELINESERVICE'].methods_by_name['Ping']._serialized_options = b'\220\002\001' _globals['_TIMELINESERVICE'].methods_by_name['GetTimeline']._loaded_options = None _globals['_TIMELINESERVICE'].methods_by_name['GetTimeline']._serialized_options = b'\220\002\001' - _globals['_GETTIMELINEREQUEST']._serialized_start=139 - _globals['_GETTIMELINEREQUEST']._serialized_end=351 - _globals['_GETTIMELINERESPONSE']._serialized_start=353 - _globals['_GETTIMELINERESPONSE']._serialized_end=432 - _globals['_CREATEEVENTREQUEST']._serialized_start=435 - _globals['_CREATEEVENTREQUEST']._serialized_end=1199 - _globals['_CREATEEVENTRESPONSE']._serialized_start=1201 - _globals['_CREATEEVENTRESPONSE']._serialized_end=1222 - _globals['_DELETEOLDEVENTSREQUEST']._serialized_start=1224 - _globals['_DELETEOLDEVENTSREQUEST']._serialized_end=1350 - _globals['_DELETEOLDEVENTSRESPONSE']._serialized_start=1352 - _globals['_DELETEOLDEVENTSRESPONSE']._serialized_end=1414 - _globals['_TIMELINESERVICE']._serialized_start=1417 - _globals['_TIMELINESERVICE']._serialized_end=1861 + _globals['_GETTIMELINEREQUEST']._serialized_start=172 + _globals['_GETTIMELINEREQUEST']._serialized_end=2068 + _globals['_GETTIMELINEREQUEST_LIMITFILTER']._serialized_start=371 + _globals['_GETTIMELINEREQUEST_LIMITFILTER']._serialized_end=406 + _globals['_GETTIMELINEREQUEST_LOGLEVELFILTER']._serialized_start=408 + _globals['_GETTIMELINEREQUEST_LOGLEVELFILTER']._serialized_end=490 + _globals['_GETTIMELINEREQUEST_DEPLOYMENTFILTER']._serialized_start=492 + _globals['_GETTIMELINEREQUEST_DEPLOYMENTFILTER']._serialized_end=544 + _globals['_GETTIMELINEREQUEST_REQUESTFILTER']._serialized_start=546 + _globals['_GETTIMELINEREQUEST_REQUESTFILTER']._serialized_end=589 + _globals['_GETTIMELINEREQUEST_EVENTTYPEFILTER']._serialized_start=591 + _globals['_GETTIMELINEREQUEST_EVENTTYPEFILTER']._serialized_end=679 + _globals['_GETTIMELINEREQUEST_TIMEFILTER']._serialized_start=682 + _globals['_GETTIMELINEREQUEST_TIMEFILTER']._serialized_end=852 + _globals['_GETTIMELINEREQUEST_IDFILTER']._serialized_start=854 + _globals['_GETTIMELINEREQUEST_IDFILTER']._serialized_end=969 + _globals['_GETTIMELINEREQUEST_CALLFILTER']._serialized_start=972 + _globals['_GETTIMELINEREQUEST_CALLFILTER']._serialized_end=1125 + _globals['_GETTIMELINEREQUEST_MODULEFILTER']._serialized_start=1127 + _globals['_GETTIMELINEREQUEST_MODULEFILTER']._serialized_end=1199 + _globals['_GETTIMELINEREQUEST_FILTER']._serialized_start=1202 + _globals['_GETTIMELINEREQUEST_FILTER']._serialized_end=2005 + _globals['_GETTIMELINEREQUEST_ORDER']._serialized_start=2007 + _globals['_GETTIMELINEREQUEST_ORDER']._serialized_end=2068 + _globals['_GETTIMELINERESPONSE']._serialized_start=2070 + _globals['_GETTIMELINERESPONSE']._serialized_end=2149 + _globals['_CREATEEVENTREQUEST']._serialized_start=2152 + _globals['_CREATEEVENTREQUEST']._serialized_end=2916 + _globals['_CREATEEVENTRESPONSE']._serialized_start=2918 + _globals['_CREATEEVENTRESPONSE']._serialized_end=2939 + _globals['_DELETEOLDEVENTSREQUEST']._serialized_start=2941 + _globals['_DELETEOLDEVENTSREQUEST']._serialized_end=3067 + _globals['_DELETEOLDEVENTSRESPONSE']._serialized_start=3069 + _globals['_DELETEOLDEVENTSRESPONSE']._serialized_end=3131 + _globals['_TIMELINESERVICE']._serialized_start=3134 + _globals['_TIMELINESERVICE']._serialized_end=3578 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.pyi b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.pyi index 4f24d12d8c..fb8216e2ca 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.pyi +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/timeline/v1/timeline_pb2.pyi @@ -1,6 +1,8 @@ +from google.protobuf import timestamp_pb2 as _timestamp_pb2 from xyz.block.ftl.timeline.v1 import event_pb2 as _event_pb2 from xyz.block.ftl.v1 import ftl_pb2 as _ftl_pb2 from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union @@ -8,16 +10,98 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map DESCRIPTOR: _descriptor.FileDescriptor class GetTimelineRequest(_message.Message): - __slots__ = ("deployment_key", "since_id", "limit", "event_types") - DEPLOYMENT_KEY_FIELD_NUMBER: _ClassVar[int] - SINCE_ID_FIELD_NUMBER: _ClassVar[int] + __slots__ = ("filters", "limit", "order") + class Order(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + ORDER_UNSPECIFIED: _ClassVar[GetTimelineRequest.Order] + ORDER_ASC: _ClassVar[GetTimelineRequest.Order] + ORDER_DESC: _ClassVar[GetTimelineRequest.Order] + ORDER_UNSPECIFIED: GetTimelineRequest.Order + ORDER_ASC: GetTimelineRequest.Order + ORDER_DESC: GetTimelineRequest.Order + class LimitFilter(_message.Message): + __slots__ = ("limit",) + LIMIT_FIELD_NUMBER: _ClassVar[int] + limit: int + def __init__(self, limit: _Optional[int] = ...) -> None: ... + class LogLevelFilter(_message.Message): + __slots__ = ("log_level",) + LOG_LEVEL_FIELD_NUMBER: _ClassVar[int] + log_level: _event_pb2.LogLevel + def __init__(self, log_level: _Optional[_Union[_event_pb2.LogLevel, str]] = ...) -> None: ... + class DeploymentFilter(_message.Message): + __slots__ = ("deployments",) + DEPLOYMENTS_FIELD_NUMBER: _ClassVar[int] + deployments: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, deployments: _Optional[_Iterable[str]] = ...) -> None: ... + class RequestFilter(_message.Message): + __slots__ = ("requests",) + REQUESTS_FIELD_NUMBER: _ClassVar[int] + requests: _containers.RepeatedScalarFieldContainer[str] + def __init__(self, requests: _Optional[_Iterable[str]] = ...) -> None: ... + class EventTypeFilter(_message.Message): + __slots__ = ("event_types",) + EVENT_TYPES_FIELD_NUMBER: _ClassVar[int] + event_types: _containers.RepeatedScalarFieldContainer[_event_pb2.EventType] + def __init__(self, event_types: _Optional[_Iterable[_Union[_event_pb2.EventType, str]]] = ...) -> None: ... + class TimeFilter(_message.Message): + __slots__ = ("older_than", "newer_than") + OLDER_THAN_FIELD_NUMBER: _ClassVar[int] + NEWER_THAN_FIELD_NUMBER: _ClassVar[int] + older_than: _timestamp_pb2.Timestamp + newer_than: _timestamp_pb2.Timestamp + def __init__(self, older_than: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ..., newer_than: _Optional[_Union[_timestamp_pb2.Timestamp, _Mapping]] = ...) -> None: ... + class IDFilter(_message.Message): + __slots__ = ("lower_than", "higher_than") + LOWER_THAN_FIELD_NUMBER: _ClassVar[int] + HIGHER_THAN_FIELD_NUMBER: _ClassVar[int] + lower_than: int + higher_than: int + def __init__(self, lower_than: _Optional[int] = ..., higher_than: _Optional[int] = ...) -> None: ... + class CallFilter(_message.Message): + __slots__ = ("dest_module", "dest_verb", "source_module") + DEST_MODULE_FIELD_NUMBER: _ClassVar[int] + DEST_VERB_FIELD_NUMBER: _ClassVar[int] + SOURCE_MODULE_FIELD_NUMBER: _ClassVar[int] + dest_module: str + dest_verb: str + source_module: str + def __init__(self, dest_module: _Optional[str] = ..., dest_verb: _Optional[str] = ..., source_module: _Optional[str] = ...) -> None: ... + class ModuleFilter(_message.Message): + __slots__ = ("module", "verb") + MODULE_FIELD_NUMBER: _ClassVar[int] + VERB_FIELD_NUMBER: _ClassVar[int] + module: str + verb: str + def __init__(self, module: _Optional[str] = ..., verb: _Optional[str] = ...) -> None: ... + class Filter(_message.Message): + __slots__ = ("limit", "log_level", "deployments", "requests", "event_types", "time", "id", "call", "module") + LIMIT_FIELD_NUMBER: _ClassVar[int] + LOG_LEVEL_FIELD_NUMBER: _ClassVar[int] + DEPLOYMENTS_FIELD_NUMBER: _ClassVar[int] + REQUESTS_FIELD_NUMBER: _ClassVar[int] + EVENT_TYPES_FIELD_NUMBER: _ClassVar[int] + TIME_FIELD_NUMBER: _ClassVar[int] + ID_FIELD_NUMBER: _ClassVar[int] + CALL_FIELD_NUMBER: _ClassVar[int] + MODULE_FIELD_NUMBER: _ClassVar[int] + limit: GetTimelineRequest.LimitFilter + log_level: GetTimelineRequest.LogLevelFilter + deployments: GetTimelineRequest.DeploymentFilter + requests: GetTimelineRequest.RequestFilter + event_types: GetTimelineRequest.EventTypeFilter + time: GetTimelineRequest.TimeFilter + id: GetTimelineRequest.IDFilter + call: GetTimelineRequest.CallFilter + module: GetTimelineRequest.ModuleFilter + def __init__(self, limit: _Optional[_Union[GetTimelineRequest.LimitFilter, _Mapping]] = ..., log_level: _Optional[_Union[GetTimelineRequest.LogLevelFilter, _Mapping]] = ..., deployments: _Optional[_Union[GetTimelineRequest.DeploymentFilter, _Mapping]] = ..., requests: _Optional[_Union[GetTimelineRequest.RequestFilter, _Mapping]] = ..., event_types: _Optional[_Union[GetTimelineRequest.EventTypeFilter, _Mapping]] = ..., time: _Optional[_Union[GetTimelineRequest.TimeFilter, _Mapping]] = ..., id: _Optional[_Union[GetTimelineRequest.IDFilter, _Mapping]] = ..., call: _Optional[_Union[GetTimelineRequest.CallFilter, _Mapping]] = ..., module: _Optional[_Union[GetTimelineRequest.ModuleFilter, _Mapping]] = ...) -> None: ... + FILTERS_FIELD_NUMBER: _ClassVar[int] LIMIT_FIELD_NUMBER: _ClassVar[int] - EVENT_TYPES_FIELD_NUMBER: _ClassVar[int] - deployment_key: str - since_id: int + ORDER_FIELD_NUMBER: _ClassVar[int] + filters: _containers.RepeatedCompositeFieldContainer[GetTimelineRequest.Filter] limit: int - event_types: _containers.RepeatedScalarFieldContainer[_event_pb2.EventType] - def __init__(self, deployment_key: _Optional[str] = ..., since_id: _Optional[int] = ..., limit: _Optional[int] = ..., event_types: _Optional[_Iterable[_Union[_event_pb2.EventType, str]]] = ...) -> None: ... + order: GetTimelineRequest.Order + def __init__(self, filters: _Optional[_Iterable[_Union[GetTimelineRequest.Filter, _Mapping]]] = ..., limit: _Optional[int] = ..., order: _Optional[_Union[GetTimelineRequest.Order, str]] = ...) -> None: ... class GetTimelineResponse(_message.Message): __slots__ = ("events",)