Compare commits

..

No commits in common. "master" and "api/go/v4.11.0-test.2" have entirely different histories.

59 changed files with 1042 additions and 1738 deletions

12
Cargo.lock generated
View File

@ -611,7 +611,7 @@ dependencies = [
[[package]]
name = "backend"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"aes-kw",
"anyhow",
@ -813,7 +813,7 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chirpstack"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"aes",
"anyhow",
@ -907,7 +907,7 @@ dependencies = [
[[package]]
name = "chirpstack_api"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"hex",
"pbjson",
@ -924,7 +924,7 @@ dependencies = [
[[package]]
name = "chirpstack_integration"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"anyhow",
"async-trait",
@ -2668,7 +2668,7 @@ dependencies = [
[[package]]
name = "lrwn"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"aes",
"anyhow",
@ -2682,7 +2682,7 @@ dependencies = [
[[package]]
name = "lrwn_filters"
version = "4.11.1"
version = "4.11.0-test.2"
dependencies = [
"hex",
"lrwn",

View File

@ -6,10 +6,11 @@ dist:
cd chirpstack && make dist
# Install dev dependencies
# TODO: test latest cargo-deb and move it to shell.nix.
dev-dependencies:
cargo install cargo-deb --version 1.43.1 --locked
cargo install cargo-generate-rpm --version 0.12.1 --locked
cargo install cross --version 0.2.5
cargo install diesel_cli --version 2.2.1 --no-default-features --features postgres,sqlite
cargo install cargo-deb --version 1.43.1
cargo install cargo-generate-rpm --version 0.12.1
# Set the versions
version:

1057
api/go/api/device.pb.go vendored

File diff suppressed because it is too large Load Diff

View File

@ -76,55 +76,6 @@ func (GatewayState) EnumDescriptor() ([]byte, []int) {
return file_api_gateway_proto_rawDescGZIP(), []int{0}
}
type ListGatewaysRequest_OrderBy int32
const (
ListGatewaysRequest_NAME ListGatewaysRequest_OrderBy = 0
ListGatewaysRequest_GATEWAY_ID ListGatewaysRequest_OrderBy = 1
ListGatewaysRequest_LAST_SEEN_AT ListGatewaysRequest_OrderBy = 2
)
// Enum value maps for ListGatewaysRequest_OrderBy.
var (
ListGatewaysRequest_OrderBy_name = map[int32]string{
0: "NAME",
1: "GATEWAY_ID",
2: "LAST_SEEN_AT",
}
ListGatewaysRequest_OrderBy_value = map[string]int32{
"NAME": 0,
"GATEWAY_ID": 1,
"LAST_SEEN_AT": 2,
}
)
func (x ListGatewaysRequest_OrderBy) Enum() *ListGatewaysRequest_OrderBy {
p := new(ListGatewaysRequest_OrderBy)
*p = x
return p
}
func (x ListGatewaysRequest_OrderBy) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ListGatewaysRequest_OrderBy) Descriptor() protoreflect.EnumDescriptor {
return file_api_gateway_proto_enumTypes[1].Descriptor()
}
func (ListGatewaysRequest_OrderBy) Type() protoreflect.EnumType {
return &file_api_gateway_proto_enumTypes[1]
}
func (x ListGatewaysRequest_OrderBy) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ListGatewaysRequest_OrderBy.Descriptor instead.
func (ListGatewaysRequest_OrderBy) EnumDescriptor() ([]byte, []int) {
return file_api_gateway_proto_rawDescGZIP(), []int{7, 0}
}
type Gateway struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -638,10 +589,6 @@ type ListGatewaysRequest struct {
TenantId string `protobuf:"bytes,4,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"`
// Multicast-group ID (UUID) to filter gateways on.
MulticastGroupId string `protobuf:"bytes,5,opt,name=multicast_group_id,json=multicastGroupId,proto3" json:"multicast_group_id,omitempty"`
// If set, the given value will be used to sort by (optional).
OrderBy ListGatewaysRequest_OrderBy `protobuf:"varint,6,opt,name=order_by,json=orderBy,proto3,enum=api.ListGatewaysRequest_OrderBy" json:"order_by,omitempty"`
// If set, the sorting direction will be decending (default = ascending) (optional).
OrderByDesc bool `protobuf:"varint,7,opt,name=order_by_desc,json=orderByDesc,proto3" json:"order_by_desc,omitempty"`
}
func (x *ListGatewaysRequest) Reset() {
@ -709,20 +656,6 @@ func (x *ListGatewaysRequest) GetMulticastGroupId() string {
return ""
}
func (x *ListGatewaysRequest) GetOrderBy() ListGatewaysRequest_OrderBy {
if x != nil {
return x.OrderBy
}
return ListGatewaysRequest_NAME
}
func (x *ListGatewaysRequest) GetOrderByDesc() bool {
if x != nil {
return x.OrderByDesc
}
return false
}
type ListGatewaysResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -1852,7 +1785,7 @@ var file_api_gateway_proto_rawDesc = []byte{
0x77, 0x61, 0x79, 0x22, 0x35, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x22, 0xbe, 0x02, 0x0a, 0x13, 0x4c,
0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x22, 0xa6, 0x01, 0x0a, 0x13, 0x4c,
0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73,
@ -1863,292 +1796,282 @@ var file_api_gateway_proto_rawDesc = []byte{
0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61,
0x73, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x52, 0x10, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x47, 0x72, 0x6f, 0x75,
0x70, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18,
0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79,
0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x5f, 0x64, 0x65, 0x73,
0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79,
0x44, 0x65, 0x73, 0x63, 0x22, 0x35, 0x0a, 0x07, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12,
0x08, 0x0a, 0x04, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x41, 0x54,
0x45, 0x57, 0x41, 0x59, 0x5f, 0x49, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x41, 0x53,
0x54, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x5f, 0x41, 0x54, 0x10, 0x02, 0x22, 0x65, 0x0a, 0x14, 0x4c,
0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75,
0x6c, 0x74, 0x22, 0x48, 0x0a, 0x27, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x22, 0xb2, 0x01, 0x0a,
0x28, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6c, 0x73,
0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6c, 0x73,
0x43, 0x65, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a,
0x07, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x63, 0x61, 0x43, 0x65, 0x72, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65,
0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 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, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41,
0x74, 0x22, 0xd0, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a,
0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 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, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12,
0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 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, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x35, 0x0a,
0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72,
0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x03, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x09, 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73,
0x12, 0x3d, 0x0a, 0x13, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70,
0x65, 0x72, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x74,
0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x46, 0x72, 0x65, 0x71, 0x12,
0x3d, 0x0a, 0x13, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65,
0x72, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x72, 0x78,
0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x46, 0x72, 0x65, 0x71, 0x12, 0x39,
0x0a, 0x11, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72,
0x5f, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0e, 0x74, 0x78, 0x50, 0x61, 0x63,
0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x44, 0x72, 0x12, 0x39, 0x0a, 0x11, 0x72, 0x78, 0x5f,
0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x72, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x52, 0x0e, 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50,
0x65, 0x72, 0x44, 0x72, 0x12, 0x41, 0x0a, 0x15, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65,
0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x52, 0x12, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65,
0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa2, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05,
0x73, 0x74, 0x61, 0x72, 0x74, 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, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c,
0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 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, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x22, 0xa1, 0x01, 0x0a,
0x22, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43,
0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x13, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f,
0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
0x52, 0x11, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x11, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x70, 0x65,
0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10,
0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65,
0x22, 0x50, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65,
0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x49, 0x64, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36,
0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61,
0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
0x64, 0x5f, 0x61, 0x74, 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, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41,
0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
0x03, 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, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c,
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01,
0x70, 0x49, 0x64, 0x22, 0x65, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74,
0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x06,
0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74,
0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x48, 0x0a, 0x27, 0x47, 0x65,
0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69,
0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x49, 0x64, 0x22, 0xb2, 0x01, 0x0a, 0x28, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65,
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6c, 0x73, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x74, 0x6c, 0x73, 0x43, 0x65, 0x72, 0x74, 0x12, 0x17, 0x0a, 0x07,
0x74, 0x6c, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74,
0x6c, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x61, 0x5f, 0x63, 0x65, 0x72, 0x74,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x43, 0x65, 0x72, 0x74, 0x12, 0x39,
0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 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, 0x52, 0x0a,
0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x22, 0x65, 0x0a, 0x18, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66,
0x66, 0x73, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69,
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49,
0x64, 0x22, 0x6f, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f,
0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75,
0x6c, 0x74, 0x22, 0x8b, 0x03, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61,
0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65,
0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 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, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74,
0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
0x61, 0x74, 0x18, 0x06, 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, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12,
0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18,
0x07, 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, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x27, 0x0a,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e,
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64,
0x22, 0x53, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a,
0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0x53, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09,
0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0xd0, 0x01, 0x0a, 0x18, 0x47, 0x65,
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 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,
0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03,
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,
0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb0, 0x03, 0x0a,
0x19, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x0a, 0x72, 0x78,
0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x09,
0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x2d, 0x0a, 0x0a, 0x74, 0x78, 0x5f,
0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x09, 0x74,
0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x13, 0x74, 0x78, 0x5f, 0x70,
0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d,
0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73,
0x50, 0x65, 0x72, 0x46, 0x72, 0x65, 0x71, 0x12, 0x3d, 0x0a, 0x13, 0x72, 0x78, 0x5f, 0x70, 0x61,
0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x66, 0x72, 0x65, 0x71, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65,
0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50,
0x65, 0x72, 0x46, 0x72, 0x65, 0x71, 0x12, 0x39, 0x0a, 0x11, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63,
0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69,
0x63, 0x52, 0x0e, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x44,
0x72, 0x12, 0x39, 0x0a, 0x11, 0x72, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f,
0x70, 0x65, 0x72, 0x5f, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x0e, 0x72, 0x78,
0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x44, 0x72, 0x12, 0x41, 0x0a, 0x15,
0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x12, 0x74, 0x78, 0x50,
0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x50, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
0xa2, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75,
0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 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, 0x52,
0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x03, 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, 0x52,
0x03, 0x65, 0x6e, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72,
0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x13, 0x6d,
0x61, 0x78, 0x5f, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61,
0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x4c, 0x6f, 0x61,
0x64, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x11, 0x77,
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x52, 0x10, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x50, 0x65,
0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x22, 0x50, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52,
0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12,
0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x22, 0xcd, 0x01, 0x0a, 0x0c, 0x52,
0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61,
0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61,
0x74, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69,
0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45,
0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e,
0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e,
0x45, 0x10, 0x02, 0x32, 0xee, 0x0b, 0x0a, 0x0e, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a,
0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01,
0x2a, 0x1a, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70,
0x74, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47,
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72,
0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47,
0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c,
0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e,
0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2f, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
0x74, 0x65, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x77,
0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72,
0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44,
0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
0x26, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c,
0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x75, 0x74, 0x79, 0x2d, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2d,
0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x89, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52,
0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1b, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47,
0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x47,
0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65,
0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74, 0x65,
0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f,
0x69, 0x64, 0x7d, 0x12, 0x78, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f,
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x39,
0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x52, 0x09,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 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, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65,
0x6e, 0x5f, 0x61, 0x74, 0x18, 0x04, 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, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65, 0x6e,
0x41, 0x74, 0x22, 0x65, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14,
0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c,
0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09,
0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x6f, 0x0a, 0x19, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74,
0x61, 0x6c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c,
0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65,
0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74,
0x65, 0x6d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x8b, 0x03, 0x0a, 0x14, 0x52,
0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x4c, 0x69, 0x73, 0x74, 0x49,
0x74, 0x65, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64,
0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
0x05, 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, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 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, 0x52, 0x09, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f,
0x73, 0x65, 0x65, 0x6e, 0x5f, 0x61, 0x74, 0x18, 0x07, 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, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x53,
0x65, 0x65, 0x6e, 0x41, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x0a,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x28,
0x0a, 0x10, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x22, 0x53, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x36, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52,
0x0c, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x22, 0x53, 0x0a,
0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65,
0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x49, 0x64, 0x22, 0xcd, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64,
0x12, 0x19, 0x0a, 0x08, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73,
0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x65, 0x67, 0x69,
0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x49, 0x64, 0x2a, 0x37, 0x0a, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x74, 0x61,
0x74, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x4e, 0x45, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x45, 0x4e,
0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x4e, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x01, 0x12, 0x0b,
0x0a, 0x07, 0x4f, 0x46, 0x46, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x32, 0xee, 0x0b, 0x0a, 0x0e,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55,
0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43,
0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x18, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64,
0x7d, 0x12, 0x6a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2d,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x01, 0x2a, 0x1a, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f,
0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x2e, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x5f, 0x0a,
0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x1c, 0x2a, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52,
0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77,
0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61,
0x79, 0x73, 0x12, 0xb1, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43,
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
0x12, 0x2c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x47, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x31, 0x22, 0x2f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64,
0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x65, 0x72, 0x74, 0x69,
0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x77, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74,
0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
0x9d, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65,
0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65,
0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c,
0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x27, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x44, 0x75, 0x74, 0x79, 0x43, 0x79, 0x63, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f,
0x12, 0x2d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f,
0x7b, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x64, 0x75, 0x74,
0x79, 0x2d, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12,
0x89, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c,
0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d,
0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x78, 0x0a, 0x11, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12,
0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72,
0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xa8, 0x01,
0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x5a, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x54, 0x3a, 0x01, 0x2a, 0x1a, 0x4f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61,
0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72,
0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12,
0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61,
0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x2a,
0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72,
0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74,
0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79,
0x5f, 0x69, 0x64, 0x7d, 0x42, 0x92, 0x01, 0x0a, 0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72,
0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65,
0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63,
0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69,
0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68,
0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70,
0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0xa8, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1e, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x5a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x54, 0x3a, 0x01, 0x2a, 0x1a,
0x4f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72,
0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x72,
0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x74, 0x65, 0x6e,
0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x67,
0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d,
0x12, 0x89, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79,
0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x2a, 0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x61,
0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x2d, 0x67, 0x61, 0x74,
0x65, 0x77, 0x61, 0x79, 0x73, 0x2f, 0x7b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x7d, 0x2f, 0x7b, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x92, 0x01, 0x0a,
0x11, 0x69, 0x6f, 0x2e, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x61,
0x70, 0x69, 0x42, 0x0c, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63,
0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x63, 0x68, 0x69, 0x72, 0x70, 0x73,
0x74, 0x61, 0x63, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x34, 0x2f, 0x61,
0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e,
0x41, 0x70, 0x69, 0xca, 0x02, 0x0e, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b,
0x5c, 0x41, 0x70, 0x69, 0xe2, 0x02, 0x1a, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x5c, 0x43, 0x68, 0x69, 0x72, 0x70, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5c, 0x41, 0x70,
0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -2163,115 +2086,113 @@ func file_api_gateway_proto_rawDescGZIP() []byte {
return file_api_gateway_proto_rawDescData
}
var file_api_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_api_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 26)
var file_api_gateway_proto_goTypes = []any{
(GatewayState)(0), // 0: api.GatewayState
(ListGatewaysRequest_OrderBy)(0), // 1: api.ListGatewaysRequest.OrderBy
(*Gateway)(nil), // 2: api.Gateway
(*GatewayListItem)(nil), // 3: api.GatewayListItem
(*CreateGatewayRequest)(nil), // 4: api.CreateGatewayRequest
(*GetGatewayRequest)(nil), // 5: api.GetGatewayRequest
(*GetGatewayResponse)(nil), // 6: api.GetGatewayResponse
(*UpdateGatewayRequest)(nil), // 7: api.UpdateGatewayRequest
(*DeleteGatewayRequest)(nil), // 8: api.DeleteGatewayRequest
(*ListGatewaysRequest)(nil), // 9: api.ListGatewaysRequest
(*ListGatewaysResponse)(nil), // 10: api.ListGatewaysResponse
(*GenerateGatewayClientCertificateRequest)(nil), // 11: api.GenerateGatewayClientCertificateRequest
(*GenerateGatewayClientCertificateResponse)(nil), // 12: api.GenerateGatewayClientCertificateResponse
(*GetGatewayMetricsRequest)(nil), // 13: api.GetGatewayMetricsRequest
(*GetGatewayMetricsResponse)(nil), // 14: api.GetGatewayMetricsResponse
(*GetGatewayDutyCycleMetricsRequest)(nil), // 15: api.GetGatewayDutyCycleMetricsRequest
(*GetGatewayDutyCycleMetricsResponse)(nil), // 16: api.GetGatewayDutyCycleMetricsResponse
(*GetRelayGatewayRequest)(nil), // 17: api.GetRelayGatewayRequest
(*GetRelayGatewayResponse)(nil), // 18: api.GetRelayGatewayResponse
(*ListRelayGatewaysRequest)(nil), // 19: api.ListRelayGatewaysRequest
(*ListRelayGatewaysResponse)(nil), // 20: api.ListRelayGatewaysResponse
(*RelayGatewayListItem)(nil), // 21: api.RelayGatewayListItem
(*UpdateRelayGatewayRequest)(nil), // 22: api.UpdateRelayGatewayRequest
(*DeleteRelayGatewayRequest)(nil), // 23: api.DeleteRelayGatewayRequest
(*RelayGateway)(nil), // 24: api.RelayGateway
nil, // 25: api.Gateway.TagsEntry
nil, // 26: api.Gateway.MetadataEntry
nil, // 27: api.GatewayListItem.PropertiesEntry
(*common.Location)(nil), // 28: common.Location
(*timestamppb.Timestamp)(nil), // 29: google.protobuf.Timestamp
(common.Aggregation)(0), // 30: common.Aggregation
(*common.Metric)(nil), // 31: common.Metric
(*emptypb.Empty)(nil), // 32: google.protobuf.Empty
(*Gateway)(nil), // 1: api.Gateway
(*GatewayListItem)(nil), // 2: api.GatewayListItem
(*CreateGatewayRequest)(nil), // 3: api.CreateGatewayRequest
(*GetGatewayRequest)(nil), // 4: api.GetGatewayRequest
(*GetGatewayResponse)(nil), // 5: api.GetGatewayResponse
(*UpdateGatewayRequest)(nil), // 6: api.UpdateGatewayRequest
(*DeleteGatewayRequest)(nil), // 7: api.DeleteGatewayRequest
(*ListGatewaysRequest)(nil), // 8: api.ListGatewaysRequest
(*ListGatewaysResponse)(nil), // 9: api.ListGatewaysResponse
(*GenerateGatewayClientCertificateRequest)(nil), // 10: api.GenerateGatewayClientCertificateRequest
(*GenerateGatewayClientCertificateResponse)(nil), // 11: api.GenerateGatewayClientCertificateResponse
(*GetGatewayMetricsRequest)(nil), // 12: api.GetGatewayMetricsRequest
(*GetGatewayMetricsResponse)(nil), // 13: api.GetGatewayMetricsResponse
(*GetGatewayDutyCycleMetricsRequest)(nil), // 14: api.GetGatewayDutyCycleMetricsRequest
(*GetGatewayDutyCycleMetricsResponse)(nil), // 15: api.GetGatewayDutyCycleMetricsResponse
(*GetRelayGatewayRequest)(nil), // 16: api.GetRelayGatewayRequest
(*GetRelayGatewayResponse)(nil), // 17: api.GetRelayGatewayResponse
(*ListRelayGatewaysRequest)(nil), // 18: api.ListRelayGatewaysRequest
(*ListRelayGatewaysResponse)(nil), // 19: api.ListRelayGatewaysResponse
(*RelayGatewayListItem)(nil), // 20: api.RelayGatewayListItem
(*UpdateRelayGatewayRequest)(nil), // 21: api.UpdateRelayGatewayRequest
(*DeleteRelayGatewayRequest)(nil), // 22: api.DeleteRelayGatewayRequest
(*RelayGateway)(nil), // 23: api.RelayGateway
nil, // 24: api.Gateway.TagsEntry
nil, // 25: api.Gateway.MetadataEntry
nil, // 26: api.GatewayListItem.PropertiesEntry
(*common.Location)(nil), // 27: common.Location
(*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp
(common.Aggregation)(0), // 29: common.Aggregation
(*common.Metric)(nil), // 30: common.Metric
(*emptypb.Empty)(nil), // 31: google.protobuf.Empty
}
var file_api_gateway_proto_depIdxs = []int32{
28, // 0: api.Gateway.location:type_name -> common.Location
25, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
26, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
28, // 3: api.GatewayListItem.location:type_name -> common.Location
27, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
29, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
29, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
29, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
27, // 0: api.Gateway.location:type_name -> common.Location
24, // 1: api.Gateway.tags:type_name -> api.Gateway.TagsEntry
25, // 2: api.Gateway.metadata:type_name -> api.Gateway.MetadataEntry
27, // 3: api.GatewayListItem.location:type_name -> common.Location
26, // 4: api.GatewayListItem.properties:type_name -> api.GatewayListItem.PropertiesEntry
28, // 5: api.GatewayListItem.created_at:type_name -> google.protobuf.Timestamp
28, // 6: api.GatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
28, // 7: api.GatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
0, // 8: api.GatewayListItem.state:type_name -> api.GatewayState
2, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway
2, // 10: api.GetGatewayResponse.gateway:type_name -> api.Gateway
29, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
29, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
29, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
2, // 14: api.UpdateGatewayRequest.gateway:type_name -> api.Gateway
1, // 15: api.ListGatewaysRequest.order_by:type_name -> api.ListGatewaysRequest.OrderBy
3, // 16: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem
29, // 17: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
29, // 18: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
29, // 19: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
30, // 20: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
31, // 21: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
31, // 22: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
31, // 23: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
31, // 24: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
31, // 25: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
31, // 26: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
31, // 27: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
29, // 28: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp
29, // 29: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp
31, // 30: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric
31, // 31: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric
24, // 32: api.GetRelayGatewayResponse.relay_gateway:type_name -> api.RelayGateway
29, // 33: api.GetRelayGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
29, // 34: api.GetRelayGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
29, // 35: api.GetRelayGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
21, // 36: api.ListRelayGatewaysResponse.result:type_name -> api.RelayGatewayListItem
29, // 37: api.RelayGatewayListItem.created_at:type_name -> google.protobuf.Timestamp
29, // 38: api.RelayGatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
29, // 39: api.RelayGatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
0, // 40: api.RelayGatewayListItem.state:type_name -> api.GatewayState
24, // 41: api.UpdateRelayGatewayRequest.relay_gateway:type_name -> api.RelayGateway
4, // 42: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
5, // 43: api.GatewayService.Get:input_type -> api.GetGatewayRequest
7, // 44: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
8, // 45: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
9, // 46: api.GatewayService.List:input_type -> api.ListGatewaysRequest
11, // 47: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
13, // 48: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
15, // 49: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest
17, // 50: api.GatewayService.GetRelayGateway:input_type -> api.GetRelayGatewayRequest
19, // 51: api.GatewayService.ListRelayGateways:input_type -> api.ListRelayGatewaysRequest
22, // 52: api.GatewayService.UpdateRelayGateway:input_type -> api.UpdateRelayGatewayRequest
23, // 53: api.GatewayService.DeleteRelayGateway:input_type -> api.DeleteRelayGatewayRequest
32, // 54: api.GatewayService.Create:output_type -> google.protobuf.Empty
6, // 55: api.GatewayService.Get:output_type -> api.GetGatewayResponse
32, // 56: api.GatewayService.Update:output_type -> google.protobuf.Empty
32, // 57: api.GatewayService.Delete:output_type -> google.protobuf.Empty
10, // 58: api.GatewayService.List:output_type -> api.ListGatewaysResponse
12, // 59: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
14, // 60: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse
16, // 61: api.GatewayService.GetDutyCycleMetrics:output_type -> api.GetGatewayDutyCycleMetricsResponse
18, // 62: api.GatewayService.GetRelayGateway:output_type -> api.GetRelayGatewayResponse
20, // 63: api.GatewayService.ListRelayGateways:output_type -> api.ListRelayGatewaysResponse
32, // 64: api.GatewayService.UpdateRelayGateway:output_type -> google.protobuf.Empty
32, // 65: api.GatewayService.DeleteRelayGateway:output_type -> google.protobuf.Empty
54, // [54:66] is the sub-list for method output_type
42, // [42:54] is the sub-list for method input_type
42, // [42:42] is the sub-list for extension type_name
42, // [42:42] is the sub-list for extension extendee
0, // [0:42] is the sub-list for field type_name
1, // 9: api.CreateGatewayRequest.gateway:type_name -> api.Gateway
1, // 10: api.GetGatewayResponse.gateway:type_name -> api.Gateway
28, // 11: api.GetGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
28, // 12: api.GetGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
28, // 13: api.GetGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
1, // 14: api.UpdateGatewayRequest.gateway:type_name -> api.Gateway
2, // 15: api.ListGatewaysResponse.result:type_name -> api.GatewayListItem
28, // 16: api.GenerateGatewayClientCertificateResponse.expires_at:type_name -> google.protobuf.Timestamp
28, // 17: api.GetGatewayMetricsRequest.start:type_name -> google.protobuf.Timestamp
28, // 18: api.GetGatewayMetricsRequest.end:type_name -> google.protobuf.Timestamp
29, // 19: api.GetGatewayMetricsRequest.aggregation:type_name -> common.Aggregation
30, // 20: api.GetGatewayMetricsResponse.rx_packets:type_name -> common.Metric
30, // 21: api.GetGatewayMetricsResponse.tx_packets:type_name -> common.Metric
30, // 22: api.GetGatewayMetricsResponse.tx_packets_per_freq:type_name -> common.Metric
30, // 23: api.GetGatewayMetricsResponse.rx_packets_per_freq:type_name -> common.Metric
30, // 24: api.GetGatewayMetricsResponse.tx_packets_per_dr:type_name -> common.Metric
30, // 25: api.GetGatewayMetricsResponse.rx_packets_per_dr:type_name -> common.Metric
30, // 26: api.GetGatewayMetricsResponse.tx_packets_per_status:type_name -> common.Metric
28, // 27: api.GetGatewayDutyCycleMetricsRequest.start:type_name -> google.protobuf.Timestamp
28, // 28: api.GetGatewayDutyCycleMetricsRequest.end:type_name -> google.protobuf.Timestamp
30, // 29: api.GetGatewayDutyCycleMetricsResponse.max_load_percentage:type_name -> common.Metric
30, // 30: api.GetGatewayDutyCycleMetricsResponse.window_percentage:type_name -> common.Metric
23, // 31: api.GetRelayGatewayResponse.relay_gateway:type_name -> api.RelayGateway
28, // 32: api.GetRelayGatewayResponse.created_at:type_name -> google.protobuf.Timestamp
28, // 33: api.GetRelayGatewayResponse.updated_at:type_name -> google.protobuf.Timestamp
28, // 34: api.GetRelayGatewayResponse.last_seen_at:type_name -> google.protobuf.Timestamp
20, // 35: api.ListRelayGatewaysResponse.result:type_name -> api.RelayGatewayListItem
28, // 36: api.RelayGatewayListItem.created_at:type_name -> google.protobuf.Timestamp
28, // 37: api.RelayGatewayListItem.updated_at:type_name -> google.protobuf.Timestamp
28, // 38: api.RelayGatewayListItem.last_seen_at:type_name -> google.protobuf.Timestamp
0, // 39: api.RelayGatewayListItem.state:type_name -> api.GatewayState
23, // 40: api.UpdateRelayGatewayRequest.relay_gateway:type_name -> api.RelayGateway
3, // 41: api.GatewayService.Create:input_type -> api.CreateGatewayRequest
4, // 42: api.GatewayService.Get:input_type -> api.GetGatewayRequest
6, // 43: api.GatewayService.Update:input_type -> api.UpdateGatewayRequest
7, // 44: api.GatewayService.Delete:input_type -> api.DeleteGatewayRequest
8, // 45: api.GatewayService.List:input_type -> api.ListGatewaysRequest
10, // 46: api.GatewayService.GenerateClientCertificate:input_type -> api.GenerateGatewayClientCertificateRequest
12, // 47: api.GatewayService.GetMetrics:input_type -> api.GetGatewayMetricsRequest
14, // 48: api.GatewayService.GetDutyCycleMetrics:input_type -> api.GetGatewayDutyCycleMetricsRequest
16, // 49: api.GatewayService.GetRelayGateway:input_type -> api.GetRelayGatewayRequest
18, // 50: api.GatewayService.ListRelayGateways:input_type -> api.ListRelayGatewaysRequest
21, // 51: api.GatewayService.UpdateRelayGateway:input_type -> api.UpdateRelayGatewayRequest
22, // 52: api.GatewayService.DeleteRelayGateway:input_type -> api.DeleteRelayGatewayRequest
31, // 53: api.GatewayService.Create:output_type -> google.protobuf.Empty
5, // 54: api.GatewayService.Get:output_type -> api.GetGatewayResponse
31, // 55: api.GatewayService.Update:output_type -> google.protobuf.Empty
31, // 56: api.GatewayService.Delete:output_type -> google.protobuf.Empty
9, // 57: api.GatewayService.List:output_type -> api.ListGatewaysResponse
11, // 58: api.GatewayService.GenerateClientCertificate:output_type -> api.GenerateGatewayClientCertificateResponse
13, // 59: api.GatewayService.GetMetrics:output_type -> api.GetGatewayMetricsResponse
15, // 60: api.GatewayService.GetDutyCycleMetrics:output_type -> api.GetGatewayDutyCycleMetricsResponse
17, // 61: api.GatewayService.GetRelayGateway:output_type -> api.GetRelayGatewayResponse
19, // 62: api.GatewayService.ListRelayGateways:output_type -> api.ListRelayGatewaysResponse
31, // 63: api.GatewayService.UpdateRelayGateway:output_type -> google.protobuf.Empty
31, // 64: api.GatewayService.DeleteRelayGateway:output_type -> google.protobuf.Empty
53, // [53:65] is the sub-list for method output_type
41, // [41:53] is the sub-list for method input_type
41, // [41:41] is the sub-list for extension type_name
41, // [41:41] is the sub-list for extension extendee
0, // [0:41] is the sub-list for field type_name
}
func init() { file_api_gateway_proto_init() }
@ -2284,7 +2205,7 @@ func file_api_gateway_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_api_gateway_proto_rawDesc,
NumEnums: 2,
NumEnums: 1,
NumMessages: 26,
NumExtensions: 0,
NumServices: 1,

View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api-grpc-web",
"version": "4.11.1",
"version": "4.11.0-test.2",
"description": "Chirpstack gRPC-web API",
"license": "MIT",
"devDependencies": {

View File

@ -8,7 +8,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.11.1"
version = "4.11.0-test.2"
repositories {
mavenCentral()

2
api/js/package.json vendored
View File

@ -1,6 +1,6 @@
{
"name": "@chirpstack/chirpstack-api",
"version": "4.11.1",
"version": "4.11.0-test.2",
"description": "Chirpstack JS and TS API",
"license": "MIT",
"devDependencies": {

View File

@ -9,7 +9,7 @@ plugins {
}
group = "io.chirpstack"
version = "4.11.1"
version = "4.11.0-test.2"
repositories {
mavenCentral()

View File

@ -3,7 +3,7 @@
"description": "Chirpstack PHP API",
"license": "MIT",
"type": "library",
"version": "4.11.1",
"version": "4.11.0-test.2",
"require": {
"php": ">=7.0.0",
"grpc/grpc": "^v1.57.0",

View File

@ -332,19 +332,6 @@ message ListDevicesRequest {
// Multicst-group ID (UUID) to filter devices on.
string multicast_group_id = 5;
enum OrderBy {
NAME = 0;
DEV_EUI = 1;
LAST_SEEN_AT = 2;
DEVICE_PROFILE_NAME = 3;
}
// If set, the given value will be used to sort by (optional).
OrderBy order_by = 6;
// If set, the sorting direction will be decending (default = ascending) (optional).
bool order_by_desc = 7;
}
message ListDevicesResponse {

View File

@ -229,18 +229,6 @@ message ListGatewaysRequest {
// Multicast-group ID (UUID) to filter gateways on.
string multicast_group_id = 5;
enum OrderBy {
NAME = 0;
GATEWAY_ID = 1;
LAST_SEEN_AT = 2;
}
// If set, the given value will be used to sort by (optional).
OrderBy order_by = 6;
// If set, the sorting direction will be decending (default = ascending) (optional).
bool order_by_desc = 7;
}
message ListGatewaysResponse {

View File

@ -18,7 +18,7 @@ CLASSIFIERS = [
setup(
name='chirpstack-api',
version = "4.11.1",
version = "4.11.0-test.2",
url='https://github.com/brocaar/chirpstack-api',
author='Orne Brocaar',
author_email='info@brocaar.com',

2
api/rust/Cargo.toml vendored
View File

@ -1,7 +1,7 @@
[package]
name = "chirpstack_api"
description = "ChirpStack Protobuf / gRPC API definitions."
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
license = "MIT"
homepage = "https://www.chirpstack.io"

View File

@ -332,19 +332,6 @@ message ListDevicesRequest {
// Multicst-group ID (UUID) to filter devices on.
string multicast_group_id = 5;
enum OrderBy {
NAME = 0;
DEV_EUI = 1;
LAST_SEEN_AT = 2;
DEVICE_PROFILE_NAME = 3;
}
// If set, the given value will be used to sort by (optional).
OrderBy order_by = 6;
// If set, the sorting direction will be decending (default = ascending) (optional).
bool order_by_desc = 7;
}
message ListDevicesResponse {

View File

@ -229,18 +229,6 @@ message ListGatewaysRequest {
// Multicast-group ID (UUID) to filter gateways on.
string multicast_group_id = 5;
enum OrderBy {
NAME = 0;
GATEWAY_ID = 1;
LAST_SEEN_AT = 2;
}
// If set, the given value will be used to sort by (optional).
OrderBy order_by = 6;
// If set, the sorting direction will be decending (default = ascending) (optional).
bool order_by_desc = 7;
}
message ListGatewaysResponse {

View File

@ -1,6 +1,6 @@
[package]
name = "backend"
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
publish = false

View File

@ -3,13 +3,13 @@
description = "Library for building external ChirpStack integrations"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"
[dependencies]
chirpstack_api = { path = "../api/rust", version = "4.11.1" }
chirpstack_api = { path = "../api/rust", version = "4.11.0-test.2" }
redis = { version = "0.27", features = [
"cluster-async",
"tokio-rustls-comp",

View File

@ -3,7 +3,7 @@
description = "ChirpStack is an open-source LoRaWAN(TM) Network Server"
repository = "https://github.com/chirpstack/chirpstack"
homepage = "https://www.chirpstack.io/"
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
publish = false

View File

@ -278,15 +278,9 @@ impl DeviceService for Device {
};
let count = device::get_count(&filters).await.map_err(|e| e.status())?;
let items = device::list(
req.limit as i64,
req.offset as i64,
&filters,
req.order_by().from_proto(),
req.order_by_desc,
)
.await
.map_err(|e| e.status())?;
let items = device::list(req.limit as i64, req.offset as i64, &filters)
.await
.map_err(|e| e.status())?;
let mut resp = Response::new(api::ListDevicesResponse {
total_count: count as u32,
@ -1368,8 +1362,6 @@ pub mod test {
multicast_group_id: "".into(),
limit: 10,
offset: 0,
order_by: api::list_devices_request::OrderBy::Name.into(),
order_by_desc: true,
},
);
let list_resp = service.list(list_req).await.unwrap();

View File

@ -238,15 +238,9 @@ impl GatewayService for Gateway {
};
let count = gateway::get_count(&filters).await.map_err(|e| e.status())?;
let result = gateway::list(
req.limit as i64,
req.offset as i64,
&filters,
req.order_by().from_proto(),
req.order_by_desc,
)
.await
.map_err(|e| e.status())?;
let result = gateway::list(req.limit as i64, req.offset as i64, &filters)
.await
.map_err(|e| e.status())?;
let mut resp = Response::new(api::ListGatewaysResponse {
total_count: count as u32,

View File

@ -2,7 +2,7 @@ use chrono::{DateTime, Utc};
use crate::codec::Codec;
use crate::storage::fields::{MeasurementKind, MulticastGroupSchedulingType};
use crate::storage::{device, device::DeviceClass, gateway, metrics::Aggregation};
use crate::storage::{device::DeviceClass, metrics::Aggregation};
use chirpstack_api::{api, common};
use lrwn::region::{CommonName, MacVersion, Revision};
@ -263,27 +263,6 @@ impl ToProto<common::DeviceClass> for DeviceClass {
}
}
impl FromProto<device::OrderBy> for api::list_devices_request::OrderBy {
fn from_proto(self) -> device::OrderBy {
match self {
Self::Name => device::OrderBy::Name,
Self::DevEui => device::OrderBy::DevEui,
Self::LastSeenAt => device::OrderBy::LastSeenAt,
Self::DeviceProfileName => device::OrderBy::DeviceProfileName,
}
}
}
impl FromProto<gateway::OrderBy> for api::list_gateways_request::OrderBy {
fn from_proto(self) -> gateway::OrderBy {
match self {
Self::Name => gateway::OrderBy::Name,
Self::GatewayId => gateway::OrderBy::GatewayId,
Self::LastSeenAt => gateway::OrderBy::LastSeenAt,
}
}
}
pub fn datetime_to_prost_timestamp(dt: &DateTime<Utc>) -> prost_types::Timestamp {
let ts = dt.timestamp_nanos_opt().unwrap_or_default();

View File

@ -28,12 +28,6 @@ struct ClerkUserinfo {
pub user_id: String,
}
#[derive(Deserialize)]
struct YandexUserinfo {
pub default_email: String,
pub id: String,
}
#[derive(Deserialize)]
pub struct CallbackArgs {
pub code: String,
@ -135,11 +129,9 @@ pub async fn get_user(code: &str, state: &str) -> Result<User> {
let conf = config::get();
let provider = conf.user_authentication.oauth2.provider.clone();
let userinfo_url = conf.user_authentication.oauth2.userinfo_url.clone();
let assume_email_verified = conf.user_authentication.oauth2.assume_email_verified;
match provider.as_ref() {
"clerk" => get_clerk_user(access_token, &userinfo_url).await,
"yandex" => get_yandex_user(access_token, &userinfo_url, assume_email_verified).await,
_ => Err(anyhow!("Unsupported OAuth2 provider: {}", provider)),
}
}
@ -163,25 +155,6 @@ async fn get_clerk_user(token: &str, url: &str) -> Result<User> {
})
}
async fn get_yandex_user(token: &str, url: &str, assume_email_verified: bool) -> Result<User> {
let client = reqwest::Client::new();
let auth_header = format!("Bearer {}", token);
let resp: YandexUserinfo = client
.get(url)
.header(AUTHORIZATION, auth_header)
.send()
.await?
.json()
.await?;
Ok(User {
email: resp.default_email,
email_verified: assume_email_verified,
external_id: resp.id,
})
}
async fn store_verifier(
token: &oauth2::CsrfToken,
verifier: &oauth2::PkceCodeVerifier,

View File

@ -5,7 +5,6 @@ use std::time::Duration;
use anyhow::Result;
use async_trait::async_trait;
use chrono::Utc;
use handlebars::Handlebars;
use prometheus_client::encoding::EncodeLabelSet;
use prometheus_client::metrics::counter::Counter;
@ -360,11 +359,6 @@ async fn message_callback(
event.v4_migrate();
}
if let Some(rx_info) = &mut event.rx_info {
set_gateway_json(&rx_info.gateway_id, json);
rx_info.ns_time = Some(Utc::now().into());
}
tokio::spawn(uplink::deduplicate_uplink(
region_common_name,
region_config_id.to_string(),

View File

@ -1,12 +1,9 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
use async_trait::async_trait;
use base64::{engine::general_purpose, Engine as _};
use prost::Message;
use reqwest::Client;
use tracing::{info, trace};
use super::Integration as IntegrationTrait;
@ -14,25 +11,13 @@ use crate::storage::application::AwsSnsConfiguration;
use chirpstack_api::api::Encoding;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
json: bool,
access_key_id: String,
secret_access_key: String,
region: String,
topic_arn: String,
client: reqwest::Client,
}
impl Integration {
@ -50,6 +35,7 @@ impl Integration {
access_key_id: conf.access_key_id.clone(),
secret_access_key: conf.secret_access_key.clone(),
region: conf.region.clone(),
client: reqwest::Client::new(),
})
}
@ -111,7 +97,7 @@ impl Integration {
headers.insert(reqwest::header::AUTHORIZATION, s.parse()?);
get_client()
self.client
.post(url)
.headers(headers)
.body(body)

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use anyhow::Result;
@ -17,20 +16,8 @@ use crate::storage::application::AzureServiceBusConfiguration;
use chirpstack_api::api::Encoding;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
timeout: Duration,
json: bool,
uri: String,
key_name: String,
@ -44,6 +31,7 @@ impl Integration {
let kv = parse_connection_string(&conf.connection_string);
Ok(Integration {
timeout: Duration::from_secs(5),
json: match Encoding::try_from(conf.encoding)
.map_err(|_| anyhow!("Invalid encoding"))?
{
@ -77,6 +65,7 @@ impl Integration {
&(SystemTime::now() + Duration::from_secs(60 * 5)),
)?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(AUTHORIZATION, token.parse()?);
@ -100,7 +89,7 @@ impl Integration {
);
info!(event = %event, dev_eui = %dev_eui, "Publishing event");
let res = get_client()
let res = client
.post(format!("{}/messages", self.uri))
.body(pl.to_string())
.headers(headers)
@ -318,6 +307,7 @@ pub mod test {
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
json: true,
uri: server.url(""),
key_name: "key-name".to_string(),

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::{Context, Result};
@ -17,24 +16,12 @@ use crate::storage::application::GcpPubSubConfiguration;
use chirpstack_api::api::Encoding;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
json: bool,
project_id: String,
topic_name: String,
service_account: gcp_auth::CustomServiceAccount,
timeout: Duration,
}
#[derive(Serialize)]
@ -70,6 +57,7 @@ impl Integration {
project_id: conf.project_id.clone(),
topic_name: conf.topic_name.clone(),
service_account,
timeout: Duration::from_secs(5),
})
}
@ -105,6 +93,7 @@ impl Integration {
.await
.context("Get GCP bearer token")?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(
@ -112,7 +101,7 @@ impl Integration {
format!("Bearer {}", token.as_str()).parse().unwrap(),
);
let res = get_client()
let res = client
.post(format!(
"https://pubsub.googleapis.com/v1/{}:publish",
topic

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -13,20 +12,8 @@ use super::Integration as IntegrationTrait;
use crate::storage::application::HttpConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
timeout: Duration,
endpoints: Vec<String>,
headers: HashMap<String, String>,
json: bool,
@ -37,6 +24,7 @@ impl Integration {
trace!("Initializing http integration");
Integration {
timeout: Duration::from_secs(5),
headers: conf.headers.clone(),
json: conf.json,
endpoints: conf
@ -48,6 +36,7 @@ impl Integration {
}
async fn post_event(&self, event: &str, b: Vec<u8>) -> Result<()> {
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
for (k, v) in &self.headers {
@ -62,7 +51,7 @@ impl Integration {
for url in &self.endpoints {
info!(event = %event, url = %url, "Posting event");
let res = get_client()
let res = client
.post(url)
.body(b.clone())
.query(&[("event", event)])
@ -225,6 +214,7 @@ pub mod test {
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
endpoints: vec![server.url("/")],
headers: [("Foo".to_string(), "Bar".to_string())]
.iter()

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -14,19 +13,6 @@ use crate::codec;
use crate::storage::application::IftttConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
#[derive(Serialize, Deserialize)]
struct Values {
#[serde(skip_serializing_if = "String::is_empty")]
@ -77,16 +63,12 @@ impl Integration {
format!("{}/trigger/{}/with/key/{}", self.server, event, self.key)
};
let client = Client::builder().timeout(Duration::from_secs(5)).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
info!(event = %event, "Sending event to IFTTT");
let res = get_client()
.post(url)
.json(&v)
.headers(headers)
.send()
.await?;
let res = client.post(url).json(&v).headers(headers).send().await?;
match res.error_for_status() {
Ok(_) => Ok(()),
Err(e) => {

View File

@ -1,6 +1,5 @@
use std::collections::HashMap;
use std::fmt;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -14,20 +13,8 @@ use crate::storage::application::InfluxDbConfiguration;
use chirpstack_api::api::{InfluxDbPrecision, InfluxDbVersion};
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
timeout: Duration,
endpoint: String,
version: InfluxDbVersion,
@ -49,6 +36,7 @@ impl Integration {
trace!("Initializing InfluxDB integration");
Ok(Integration {
timeout: Duration::from_secs(5),
endpoint: conf.endpoint.clone(),
version: InfluxDbVersion::try_from(conf.version)
.map_err(|_| anyhow!("Invalid version"))?,
@ -78,6 +66,8 @@ impl Integration {
measurements.sort();
let body = measurements.join("\n");
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "text/plain".parse().unwrap());
if self.version == InfluxDbVersion::Influxdb2 {
@ -97,7 +87,7 @@ impl Integration {
}
}
let mut req = get_client()
let mut req = client
.post(&self.endpoint)
.body(body)
.query(&query)
@ -487,6 +477,7 @@ pub mod test {
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
endpoint: server.url("/write"),
version: InfluxDbVersion::Influxdb1,
db: "testdb".into(),
@ -841,6 +832,7 @@ device_uplink,application_name=test-app,dev_eui=0102030405060708,device_name=tes
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
endpoint: server.url("/write"),
version: InfluxDbVersion::Influxdb2,
db: "".into(),

View File

@ -1,5 +1,4 @@
use std::fmt;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -14,19 +13,6 @@ use crate::gpstime::ToGpsTime;
use crate::uplink::helpers;
use lrwn::EUI64;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
#[derive(Error, Debug)]
pub enum Error {
#[error("No location")]
@ -39,6 +25,7 @@ pub enum Error {
pub struct ApiClient {
uri: String,
token: String,
timeout: Duration,
}
impl ApiClient {
@ -46,6 +33,7 @@ impl ApiClient {
ApiClient {
uri: uri.to_string(),
token: token.to_string(),
timeout: Duration::from_secs(5),
}
}
@ -129,6 +117,7 @@ impl ApiClient {
pub async fn uplink_send(&self, req: &UplinkRequest) -> Result<UplinkResponse> {
let endpoint = format!("{}/api/v1/device/send", self.uri);
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(
@ -136,7 +125,7 @@ impl ApiClient {
self.token.parse()?,
);
let res = get_client()
let res = client
.post(endpoint)
.headers(headers)
.json(req)
@ -149,6 +138,7 @@ impl ApiClient {
async fn request(&self, endpoint: &str, body: &str) -> Result<Response> {
let endpoint = format!("{}{}", self.uri, endpoint);
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(
@ -156,7 +146,7 @@ impl ApiClient {
self.token.parse()?,
);
let res = get_client()
let res = client
.post(endpoint)
.body(body.to_string())
.headers(headers)
@ -170,6 +160,7 @@ impl ApiClient {
async fn v3_request(&self, endpoint: &str, body: &str) -> Result<V3Response> {
let endpoint = format!("{}{}", self.uri, endpoint);
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
headers.insert(
@ -177,7 +168,7 @@ impl ApiClient {
self.token.parse()?,
);
let res = get_client()
let res = client
.post(endpoint)
.body(body.to_string())
.headers(headers)

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -14,19 +13,6 @@ use super::Integration as IntegrationTrait;
use crate::storage::application::MyDevicesConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
#[derive(Serialize)]
struct UplinkPayload {
#[serde(rename = "correlationID")]
@ -102,6 +88,7 @@ struct Location {
}
pub struct Integration {
timeout: Duration,
endpoint: String,
}
@ -109,6 +96,7 @@ impl Integration {
pub fn new(conf: &MyDevicesConfiguration) -> Integration {
trace!("Initializing myDevices integration");
Integration {
timeout: Duration::from_secs(5),
endpoint: conf.endpoint.clone(),
}
}
@ -132,10 +120,11 @@ impl IntegrationTrait for Integration {
let pl = UplinkPayload::from_uplink_event(pl);
let b = serde_json::to_string(&pl)?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
let req = get_client()
let req = client
.post(&self.endpoint)
.body(b)
.headers(headers)
@ -215,6 +204,7 @@ pub mod test {
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
endpoint: server.url("/"),
};

View File

@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -13,20 +12,8 @@ use super::Integration as IntegrationTrait;
use crate::storage::application::PilotThingsConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
timeout: Duration,
server: String,
token: String,
}
@ -36,6 +23,7 @@ impl Integration {
trace!("Initializing Pilot Things integration");
Integration {
timeout: Duration::from_secs(5),
server: conf.server.clone(),
token: conf.token.clone(),
}
@ -57,10 +45,11 @@ impl IntegrationTrait for Integration {
let pl = UplinkPayload::from_uplink_event(pl);
let b = serde_json::to_string(&pl)?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
let res = get_client()
let res = client
.post(endpoint)
.body(b)
.query(&[("token", self.token.clone())])
@ -193,6 +182,7 @@ pub mod test {
let server = MockServer::start();
let i = Integration {
timeout: Duration::from_secs(5),
server: server.url(""),
token: "foo-token".into(),
};

View File

@ -1,5 +1,4 @@
use std::collections::{BTreeMap, HashMap};
use std::sync::OnceLock;
use std::time::Duration;
use anyhow::Result;
@ -13,21 +12,9 @@ use super::Integration as IntegrationTrait;
use crate::storage::application::ThingsBoardConfiguration;
use chirpstack_api::integration;
static CLIENT: OnceLock<Client> = OnceLock::new();
fn get_client() -> Client {
CLIENT
.get_or_init(|| {
Client::builder()
.timeout(Duration::from_secs(5))
.build()
.unwrap()
})
.clone()
}
pub struct Integration {
server: String,
timeout: Duration,
}
impl Integration {
@ -35,6 +22,7 @@ impl Integration {
trace!("Initializing ThingsBoard integration");
Integration {
timeout: Duration::from_secs(5),
server: conf.server.clone(),
}
}
@ -51,10 +39,11 @@ impl Integration {
let endpoint = format!("{}/api/v1/{}/attributes", self.server, access_token);
let b = serde_json::to_string(&attributes)?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
let res = get_client()
let res = client
.post(endpoint)
.body(b)
.headers(headers)
@ -76,10 +65,11 @@ impl Integration {
let endpoint = format!("{}/api/v1/{}/telemetry", self.server, access_token);
let b = serde_json::to_string(&telemetry)?;
let client = Client::builder().timeout(self.timeout).build()?;
let mut headers = HeaderMap::new();
headers.insert(CONTENT_TYPE, "application/json".parse().unwrap());
let res = get_client()
let res = client
.post(endpoint)
.body(b)
.headers(headers)
@ -333,6 +323,7 @@ pub mod test {
let i = Integration {
server: server.url(""),
timeout: Duration::from_secs(5),
};
let mut vars: HashMap<String, String> = HashMap::new();

View File

@ -27,40 +27,31 @@ pub fn handle(
.as_ref()
.ok_or_else(|| anyhow!("parameters can not be None"))?;
// For non-LoRa modulations, the margin will be set to 0, as it can not be calculated.
// This way, at least the gw_cnt can be provided and the end-device is able to confirm
// it is still connected.
let margin = match mod_params {
gw::modulation::Parameters::Lora(pl) => {
let required_snr = config::get_required_snr_for_sf(pl.spreading_factor as u8)?;
let mut max_snr: f32 = 0.0;
if let gw::modulation::Parameters::Lora(pl) = mod_params {
let required_snr = config::get_required_snr_for_sf(pl.spreading_factor as u8)?;
let mut max_snr: f32 = 0.0;
for (i, rx_info) in ufs.rx_info_set.iter().enumerate() {
if i == 0 || rx_info.snr > max_snr {
max_snr = rx_info.snr;
}
}
let margin = max_snr - required_snr;
if margin < 0.0 {
0.0
} else {
margin
for (i, rx_info) in ufs.rx_info_set.iter().enumerate() {
if i == 0 || rx_info.snr > max_snr {
max_snr = rx_info.snr;
}
}
_ => {
warn!("Modulation does not provide margin to LinkCheckReq");
0.0
}
};
// We always return a LinkCheckAns, even
Ok(Some(lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkCheckAns(lrwn::LinkCheckAnsPayload {
margin: margin as u8,
gw_cnt: ufs.rx_info_set.len() as u8,
}),
])))
let mut margin = max_snr - required_snr;
if margin < 0.0 {
margin = 0.0;
}
return Ok(Some(lrwn::MACCommandSet::new(vec![
lrwn::MACCommand::LinkCheckAns(lrwn::LinkCheckAnsPayload {
margin: margin as u8,
gw_cnt: ufs.rx_info_set.len() as u8,
}),
])));
}
warn!("Unsupported modulation for LinkCheckReq");
Ok(None)
}
#[cfg(test)]

View File

@ -216,15 +216,6 @@ pub struct Filters {
pub search: Option<String>,
}
#[derive(Clone, Debug, Default)]
pub enum OrderBy {
#[default]
Name,
DevEui,
LastSeenAt,
DeviceProfileName,
}
#[derive(QueryableByName, PartialEq, Eq, Debug)]
pub struct DevicesActiveInactive {
#[diesel(sql_type = diesel::sql_types::BigInt)]
@ -615,8 +606,6 @@ pub async fn list(
limit: i64,
offset: i64,
filters: &Filters,
order_by: OrderBy,
order_by_desc: bool,
) -> Result<Vec<DeviceListItem>, Error> {
let mut q = device::dsl::device
.inner_join(device_profile::table)
@ -659,26 +648,8 @@ pub async fn list(
);
}
q = match order_by_desc {
true => match order_by {
OrderBy::Name => q.order_by(device::dsl::name.desc()),
OrderBy::DevEui => q.order_by(device::dsl::dev_eui.desc()),
OrderBy::LastSeenAt => q
.order_by(device::dsl::last_seen_at.desc())
.then_order_by(device::dsl::name),
OrderBy::DeviceProfileName => q.order_by(device_profile::dsl::name.desc()),
},
false => match order_by {
OrderBy::Name => q.order_by(device::dsl::name),
OrderBy::DevEui => q.order_by(device::dsl::dev_eui),
OrderBy::LastSeenAt => q
.order_by(device::dsl::last_seen_at)
.then_order_by(device::dsl::name),
OrderBy::DeviceProfileName => q.order_by(device_profile::dsl::name),
},
};
q.limit(limit)
q.order_by(device::dsl::name)
.limit(limit)
.offset(offset)
.load(&mut get_async_db_conn().await?)
.await
@ -904,8 +875,6 @@ pub mod test {
count: usize,
limit: i64,
offset: i64,
order: OrderBy,
order_by_desc: bool,
}
pub async fn create_device(
@ -973,8 +942,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -986,8 +953,6 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -999,8 +964,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -1012,8 +975,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -1025,8 +986,6 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
];
@ -1034,15 +993,7 @@ pub mod test {
let count = get_count(&tst.filters).await.unwrap() as usize;
assert_eq!(tst.count, count);
let items = list(
tst.limit,
tst.offset,
&tst.filters,
tst.order,
tst.order_by_desc,
)
.await
.unwrap();
let items = list(tst.limit, tst.offset, &tst.filters).await.unwrap();
assert_eq!(
tst.devs
.iter()

View File

@ -110,14 +110,6 @@ pub struct Filters {
pub search: Option<String>,
}
#[derive(Clone, Debug, Default)]
pub enum OrderBy {
#[default]
Name,
GatewayId,
LastSeenAt,
}
#[derive(QueryableByName, PartialEq, Eq, Debug)]
pub struct GatewayCountsByState {
#[diesel(sql_type = diesel::sql_types::BigInt)]
@ -317,8 +309,6 @@ pub async fn list(
limit: i64,
offset: i64,
filters: &Filters,
order_by: OrderBy,
order_by_desc: bool,
) -> Result<Vec<GatewayListItem>, Error> {
let mut q = gateway::dsl::gateway
.left_join(multicast_group_gateway::table)
@ -361,24 +351,8 @@ pub async fn list(
);
}
q = match order_by_desc {
true => match order_by {
OrderBy::Name => q.order_by(gateway::dsl::name.desc()),
OrderBy::GatewayId => q.order_by(gateway::dsl::gateway_id.desc()),
OrderBy::LastSeenAt => q
.order_by(gateway::dsl::last_seen_at.desc())
.then_order_by(gateway::dsl::name),
},
false => match order_by {
OrderBy::Name => q.order_by(gateway::dsl::name),
OrderBy::GatewayId => q.order_by(gateway::dsl::gateway_id),
OrderBy::LastSeenAt => q
.order_by(gateway::dsl::last_seen_at)
.then_order_by(gateway::dsl::name),
},
};
let items = q
.order_by(gateway::dsl::name)
.limit(limit)
.offset(offset)
.load(&mut get_async_db_conn().await?)
@ -548,8 +522,6 @@ pub mod test {
count: usize,
limit: i64,
offset: i64,
order: OrderBy,
order_by_desc: bool,
}
struct RelayGatewayFilterTest<'a> {
@ -631,8 +603,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -644,8 +614,6 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -657,8 +625,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -670,8 +636,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -683,8 +647,6 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -696,8 +658,6 @@ pub mod test {
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
@ -709,47 +669,6 @@ pub mod test {
count: 0,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: false,
},
FilterTest {
filters: Filters {
tenant_id: None,
multicast_group_id: None,
search: None,
},
gws: vec![&gw],
count: 1,
limit: 10,
offset: 0,
order: OrderBy::Name,
order_by_desc: true,
},
];
@ -757,15 +676,7 @@ pub mod test {
let count = get_count(&tst.filters).await.unwrap() as usize;
assert_eq!(tst.count, count);
let items = list(
tst.limit,
tst.offset,
&tst.filters,
tst.order,
tst.order_by_desc,
)
.await
.unwrap();
let items = list(tst.limit, tst.offset, &tst.filters).await.unwrap();
assert_eq!(
tst.gws
.iter()

View File

@ -3,7 +3,7 @@
description = "Library for filtering LoRaWAN payloads on DevAddr and JoinEUIs prefixes"
homepage = "https://www.chirpstack.io/"
license = "MIT"
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2021"
repository = "https://github.com/chirpstack/chirpstack"

View File

@ -3,7 +3,7 @@
description = "Library for encoding / decoding LoRaWAN frames."
homepage = "https://www.chirpstack.io"
license = "MIT"
version = "4.11.1"
version = "4.11.0-test.2"
authors = ["Orne Brocaar <info@brocaar.com>"]
edition = "2018"
repository = "https://github.com/chirpstack/chirpstack"

View File

@ -7,21 +7,19 @@ pkgs.mkShell {
buildInputs = [
pkgs.cacert
pkgs.rustup
pkgs.protobuf
pkgs.perl
pkgs.cmake
pkgs.clang
pkgs.protobuf # api
pkgs.postgresql # needed to build the diesel cli utility
pkgs.go # go api
pkgs.protoc-gen-go # go api
pkgs.protoc-gen-go-grpc # go api
pkgs.protoc-gen-grpc-web # grpc-web api
pkgs.nodejs # js api + ui
pkgs.yarn # ui
pkgs.yarn
pkgs.protoc-gen-grpc-web # grpc-web api
pkgs.protoc-gen-go # go api
pkgs.protoc-gen-go-grpc
pkgs.openssl
pkgs.sqlite # sqlite binary + library for diesel
pkgs.postgresql # psql binary + library for diesel
pkgs.cargo-cross # cross-compiling
pkgs.diesel-cli # diesel cli
pkgs.sqlite
];
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
BINDGEN_EXTRA_CLANG_ARGS = "-I${pkgs.llvmPackages.libclang.lib}/lib/clang/${pkgs.llvmPackages.libclang.version}/include";

View File

@ -1,6 +1,6 @@
{
"name": "chirpstack-ui",
"version": "4.11.1",
"version": "4.11.0-test.2",
"private": true,
"type": "module",
"scripts": {

View File

@ -1,8 +1,7 @@
import React, { useState, useEffect, useCallback } from "react";
import { Table, TableProps } from "antd";
import { Table } from "antd";
import type { ColumnsType } from "antd/es/table";
import type { SorterResult } from "antd/es/table/interface";
import SessionStore from "../stores/SessionStore";
@ -11,13 +10,7 @@ export type GetPageCallbackFunc = (totalCount: number, rows: object[]) => void;
interface IProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
columns: ColumnsType<any>;
getPage: (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => void;
getPage: (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => void;
onRowsSelectChange?: (ids: string[]) => void;
rowKey: string;
refreshKey?: unknown;
@ -28,24 +21,33 @@ function DataTable(props: IProps) {
const [totalCount, setTotalCount] = useState<number>(0);
const [pageSize, setPageSize] = useState<number>(SessionStore.getRowsPerPage());
const [currentPage, setCurrentPage] = useState<number>(1);
const [orderBy, setOrderBy] = useState<string>("");
const [orderByDesc, setOrderByDesc] = useState<boolean>(false);
const [rows, setRows] = useState<object[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const loadPage = useCallback(
(page: number, pz: number, orderBy?: string | void, orderByDesc?: boolean | void) => {
const onChangePage = useCallback(
(page: number, pz?: number | void) => {
setLoading(true);
props.getPage(pz, (page - 1) * pz, orderBy, orderByDesc, (totalCount: number, rows: object[]) => {
if (!pz) {
pz = pageSize;
}
props.getPage(pz, (page - 1) * pz, (totalCount: number, rows: object[]) => {
setCurrentPage(page);
setTotalCount(totalCount);
setRows(rows);
setPageSize(pz || 0);
setLoading(false);
});
},
[props, pageSize],
);
const onShowSizeChange = (page: number, pageSize: number) => {
onChangePage(page, pageSize);
SessionStore.setRowsPerPage(pageSize);
};
const onRowsSelectChange = (ids: React.Key[]) => {
const idss = ids as string[];
if (props.onRowsSelectChange) {
@ -53,49 +55,9 @@ function DataTable(props: IProps) {
}
};
const onChange: TableProps<object>["onChange"] = (pagination, filters, sorter, extra) => {
let page = pagination.current;
if (!page) {
page = currentPage;
}
let pz = pagination.pageSize;
if (!pz) {
pz = pageSize;
}
SessionStore.setRowsPerPage(pz);
let firstSorter: SorterResult<object> | void = undefined;
if (Array.isArray(sorter)) {
if (sorter.length) {
firstSorter = sorter[0];
}
} else {
firstSorter = sorter;
}
let sort: string | void = undefined;
if (firstSorter) {
if (firstSorter.columnKey) {
sort = firstSorter.columnKey.toString();
if (firstSorter.order === "descend") {
setOrderByDesc(true);
} else {
setOrderByDesc(false);
}
}
}
if (!sort) {
sort = orderBy;
}
setCurrentPage(page);
setPageSize(pz || 0);
setOrderBy(sort);
};
useEffect(() => {
loadPage(currentPage, pageSize, orderBy, orderByDesc);
}, [props, currentPage, pageSize, orderBy, orderByDesc, loadPage]);
onChangePage(currentPage, pageSize);
}, [props, currentPage, pageSize, onChangePage]);
const { getPage, refreshKey, ...otherProps } = props;
let loadingProps = undefined;
@ -111,7 +73,9 @@ function DataTable(props: IProps) {
current: currentPage,
total: totalCount,
pageSize: pageSize,
onChange: onChangePage,
showSizeChanger: true,
onShowSizeChange: onShowSizeChange,
};
}
@ -128,7 +92,6 @@ function DataTable(props: IProps) {
dataSource={rows}
pagination={pagination || false}
rowSelection={rowSelection}
onChange={onChange}
{...otherProps}
/>
);

View File

@ -56,13 +56,7 @@ function ListAdminApiKeys() {
};
};
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListApiKeysRequest();
req.setLimit(limit);
req.setOffset(offset);

View File

@ -64,13 +64,7 @@ function ListTenantApiKeys(props: IProps) {
};
};
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListApiKeysRequest();
req.setLimit(limit);
req.setOffset(offset);

View File

@ -38,13 +38,7 @@ function ListApplications(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListApplicationsRequest();
req.setTenantId(props.tenant.getId());
req.setLimit(limit);

View File

@ -47,13 +47,7 @@ function ListDeviceProfileTemplates() {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListDeviceProfileTemplatesRequest();
req.setLimit(limit);
req.setOffset(offset);

View File

@ -102,13 +102,7 @@ function ListDeviceProfiles(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListDeviceProfilesRequest();
req.setTenantId(props.tenant.getId());
req.setLimit(limit);

View File

@ -5,16 +5,28 @@ import { format } from "date-fns";
import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
import { Switch, notification } from "antd";
import type { DatePickerProps } from "antd";
import { Button, Tabs, Space, Card, Row, Form, Input, InputNumber, Popconfirm, DatePicker } from "antd";
import {
Button,
Tabs,
Space,
Card,
Row,
Form,
Input,
InputNumber,
Popconfirm,
DatePicker,
DatePickerProps,
} from "antd";
import type { ColumnsType } from "antd/es/table";
import { RedoOutlined, DeleteOutlined } from "@ant-design/icons";
import { Buffer } from "buffer";
import type { GetDeviceQueueItemsResponse, Device } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import {
EnqueueDeviceQueueItemRequest,
GetDeviceQueueItemsRequest,
GetDeviceQueueItemsResponse,
Device,
FlushDeviceQueueRequest,
DeviceQueueItem,
} from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
@ -135,13 +147,7 @@ function DeviceQueue(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new GetDeviceQueueItemsRequest();
req.setDevEui(props.device.getDevEui());

View File

@ -79,7 +79,6 @@ function ListDevices(props: IProps) {
}
return "Never";
},
sorter: true,
},
{
title: "DevEUI",
@ -95,13 +94,11 @@ function ListDevices(props: IProps) {
{text}
</Link>
),
sorter: true,
},
{
title: "Name",
dataIndex: "name",
key: "name",
sorter: true,
},
{
title: "Device profile",
@ -112,7 +109,6 @@ function ListDevices(props: IProps) {
{text}
</Link>
),
sorter: true,
},
{
title: "Battery",
@ -138,32 +134,11 @@ function ListDevices(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
function getOrderBy(orderBy: string | void): ListDevicesRequest.OrderBy {
switch (orderBy) {
case "lastSeenAt":
return ListDevicesRequest.OrderBy.LAST_SEEN_AT;
case "deviceProfileName":
return ListDevicesRequest.OrderBy.DEVICE_PROFILE_NAME;
case "devEui":
return ListDevicesRequest.OrderBy.DEV_EUI;
default:
return ListDevicesRequest.OrderBy.NAME;
}
}
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListDevicesRequest();
req.setApplicationId(props.application.getId());
req.setLimit(limit);
req.setOffset(offset);
req.setOrderBy(getOrderBy(orderBy));
req.setOrderByDesc(orderByDesc || false);
DeviceStore.list(req, (resp: ListDevicesResponse) => {
const obj = resp.toObject();

View File

@ -71,7 +71,6 @@ function ListGateways(props: IProps) {
return format(ts, "yyyy-MM-dd HH:mm:ss");
}
},
sorter: true,
},
{
title: "Gateway ID",
@ -81,13 +80,11 @@ function ListGateways(props: IProps) {
render: (text, record) => (
<Link to={`/tenants/${props.tenant.getId()}/gateways/${record.gatewayId}`}>{text}</Link>
),
sorter: true,
},
{
title: "Name",
dataIndex: "name",
key: "name",
sorter: true,
},
{
title: "Region ID",
@ -100,6 +97,7 @@ function ListGateways(props: IProps) {
return <Link to={`/regions/${v}`}>{v}</Link>;
}
}
return "";
},
},
@ -114,6 +112,7 @@ function ListGateways(props: IProps) {
return v;
}
}
return "";
},
},
@ -148,30 +147,11 @@ function ListGateways(props: IProps) {
});
}, [props]);
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
function getOrderBy(orderBy: string | void): ListGatewaysRequest.OrderBy {
switch (orderBy) {
case "lastSeenAt":
return ListGatewaysRequest.OrderBy.LAST_SEEN_AT;
case "gatewayId":
return ListGatewaysRequest.OrderBy.GATEWAY_ID;
default:
return ListGatewaysRequest.OrderBy.NAME;
}
}
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListGatewaysRequest();
req.setTenantId(props.tenant.getId());
req.setLimit(limit);
req.setOffset(offset);
req.setOrderBy(getOrderBy(orderBy));
req.setOrderByDesc(orderByDesc || false);
GatewayStore.list(req, (resp: ListGatewaysResponse) => {
const obj = resp.toObject();

View File

@ -77,13 +77,7 @@ function ListRelayGateways(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListRelayGatewaysRequest();
req.setTenantId(props.tenant.getId());
req.setLimit(limit);

View File

@ -40,13 +40,7 @@ function ListMulticastGroupDevices(props: IProps) {
setSelectedRowIds(ids);
};
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListDevicesRequest();
req.setApplicationId(props.multicastGroup.getApplicationId());
req.setMulticastGroupId(props.multicastGroup.getId());

View File

@ -43,13 +43,7 @@ function ListMulticastGroupGateways(props: IProps) {
setSelectedRowIds(ids);
};
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListGatewaysRequest();
req.setTenantId(props.application.getTenantId());
req.setMulticastGroupId(props.multicastGroup.getId());

View File

@ -60,13 +60,7 @@ function ListMulticastGroups(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListMulticastGroupsRequest();
req.setApplicationId(props.application.getId());
req.setLimit(limit);

View File

@ -3,21 +3,30 @@ import { useState } from "react";
import { format } from "date-fns";
import { Timestamp } from "google-protobuf/google/protobuf/timestamp_pb";
import type { DatePickerProps } from "antd";
import { Button, Tabs, Space, Card, Row, Form, Input, InputNumber, Popconfirm, DatePicker } from "antd";
import {
Button,
Tabs,
Space,
Card,
Row,
Form,
Input,
InputNumber,
Popconfirm,
DatePicker,
DatePickerProps,
} from "antd";
import type { ColumnsType } from "antd/es/table";
import { RedoOutlined, DeleteOutlined } from "@ant-design/icons";
import { Buffer } from "buffer";
import type {
MulticastGroup,
ListMulticastGroupQueueResponse,
} from "@chirpstack/chirpstack-api-grpc-web/api/multicast_group_pb";
import {
EnqueueMulticastGroupQueueItemRequest,
ListMulticastGroupQueueRequest,
FlushMulticastGroupQueueRequest,
MulticastGroupQueueItem,
MulticastGroup,
ListMulticastGroupQueueResponse,
} from "@chirpstack/chirpstack-api-grpc-web/api/multicast_group_pb";
import { onFinishFailed } from "../helpers";
@ -78,13 +87,7 @@ function MulticastGroupQueue(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListMulticastGroupQueueRequest();
req.setMulticastGroupId(props.multicastGroup.getId());

View File

@ -63,13 +63,7 @@ function ListRelayDevices(props: IProps) {
}
};
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListRelayDevicesRequest();
req.setRelayDevEui(props.relayDevice.getDevEui());
req.setLimit(limit);

View File

@ -37,13 +37,7 @@ function ListRelays(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListRelaysRequest();
req.setApplicationId(props.application.getId());
req.setLimit(limit);

View File

@ -65,13 +65,7 @@ function ListTenantUsers(props: IProps) {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListTenantUsersRequest();
req.setTenantId(props.tenant.getId());
req.setLimit(limit);

View File

@ -92,13 +92,7 @@ function ListTenants() {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListTenantsRequest();
req.setLimit(limit);
req.setOffset(offset);

View File

@ -50,13 +50,7 @@ function ListUsers() {
},
];
const getPage = (
limit: number,
offset: number,
orderBy: string | void,
orderByDesc: boolean | void,
callbackFunc: GetPageCallbackFunc,
) => {
const getPage = (limit: number, offset: number, callbackFunc: GetPageCallbackFunc) => {
const req = new ListUsersRequest();
req.setLimit(limit);
req.setOffset(offset);