diff options
author | Sami Hiltunen <shiltunen@gitlab.com> | 2022-04-14 12:27:14 +0300 |
---|---|---|
committer | Sami Hiltunen <shiltunen@gitlab.com> | 2022-04-14 12:27:14 +0300 |
commit | c311109b15c26e1981c855bfa5c87aef02d27560 (patch) | |
tree | e976a568d9be5bc08478588415def1faa9e57008 | |
parent | 9413ca591ebe30dcb133c86d0ec53f6bc2fc30bb (diff) | |
parent | 4e9fc294b04971e588476850ecc094d4e54cd062 (diff) |
Merge branch 'smh-verify-metadata-output' into 'master'
Expose last verification time in 'praefect metadata'
Closes #4092
See merge request gitlab-org/gitaly!4466
-rw-r--r-- | cmd/praefect/subcmd_metadata.go | 6 | ||||
-rw-r--r-- | cmd/praefect/subcmd_metadata_test.go | 9 | ||||
-rw-r--r-- | internal/praefect/datastore/repository_store.go | 11 | ||||
-rw-r--r-- | internal/praefect/datastore/repository_store_test.go | 59 | ||||
-rw-r--r-- | internal/praefect/service/info/metadata.go | 7 | ||||
-rw-r--r-- | proto/go/gitalypb/praefect.pb.go | 368 | ||||
-rw-r--r-- | proto/praefect.proto | 3 | ||||
-rw-r--r-- | ruby/proto/gitaly/praefect_pb.rb | 2 |
8 files changed, 269 insertions, 196 deletions
diff --git a/cmd/praefect/subcmd_metadata.go b/cmd/praefect/subcmd_metadata.go index e913a0eec..3cc9b8292 100644 --- a/cmd/praefect/subcmd_metadata.go +++ b/cmd/praefect/subcmd_metadata.go @@ -99,9 +99,15 @@ func (cmd *metadataSubcommand) Exec(flags *flag.FlagSet, cfg config.Config) erro generationText = fmt.Sprintf("%d, behind by %d changes", replica.Generation, metadata.Generation-replica.Generation) } + verifiedAt := "unverified" + if replica.VerifiedAt.IsValid() { + verifiedAt = replica.VerifiedAt.AsTime().String() + } + cmd.println(" Generation: %s", generationText) cmd.println(" Healthy: %v", replica.Healthy) cmd.println(" Valid Primary: %v", replica.ValidPrimary) + cmd.println(" Verified At: %s", verifiedAt) } return nil } diff --git a/cmd/praefect/subcmd_metadata_test.go b/cmd/praefect/subcmd_metadata_test.go index ee433fa87..dbca8c27c 100644 --- a/cmd/praefect/subcmd_metadata_test.go +++ b/cmd/praefect/subcmd_metadata_test.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "testing" + "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/config" @@ -33,6 +34,11 @@ func TestMetadataSubcommand(t *testing.T) { require.NoError(t, rs.CreateRepository(ctx, 1, "virtual-storage", "relative-path", "replica-path", "primary", []string{"secondary-1"}, []string{"secondary-2"}, true, true)) require.NoError(t, rs.IncrementGeneration(ctx, 1, "primary", nil)) + _, err := tx.ExecContext(ctx, "UPDATE storage_repositories SET verified_at = $1 WHERE storage = 'primary'", + time.Date(2021, time.April, 1, 10, 4, 20, 64, time.UTC), + ) + require.NoError(t, err) + ln, clean := listenAndServe(t, []svcRegistrar{ registerPraefectInfoServer(info.NewServer(config.Config{}, rs, nil, nil, nil)), }) @@ -105,16 +111,19 @@ Replicas: Generation: 1, fully up to date Healthy: true Valid Primary: true + Verified At: 2021-04-01 10:04:20 +0000 UTC - Storage: "secondary-1" Assigned: true Generation: 0, behind by 1 changes Healthy: true Valid Primary: false + Verified At: unverified - Storage: "secondary-2" Assigned: true Generation: replica not yet created Healthy: false Valid Primary: false + Verified At: unverified `, stdout.String()) }) } diff --git a/internal/praefect/datastore/repository_store.go b/internal/praefect/datastore/repository_store.go index cf3dda65e..74658e212 100644 --- a/internal/praefect/datastore/repository_store.go +++ b/internal/praefect/datastore/repository_store.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "strings" + "time" "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore/glsql" @@ -629,6 +630,8 @@ type Replica struct { Healthy bool // ValidPrimary indicates whether the replica is ready to serve as the primary if necessary. ValidPrimary bool + // VerifiedAt is the last successful verification time of the replica. + VerifiedAt time.Time } // RepositoryMetadata contains the repository's metadata. @@ -773,7 +776,7 @@ repositories AS ( ), storage_repositories AS ( - SELECT repository_id, storage, storage_repositories.generation + SELECT repository_id, storage, storage_repositories.generation, verified_at FROM repositories JOIN storage_repositories USING (repository_id) ), @@ -798,7 +801,8 @@ SELECT 'Generation', COALESCE(replicas.generation, -1), 'Assigned', assigned, 'Healthy', healthy_storages.storage IS NOT NULL, - 'ValidPrimary', valid_primaries.storage IS NOT NULL + 'ValidPrimary', valid_primaries.storage IS NOT NULL, + 'VerifiedAt', verified_at ) ) ) @@ -808,7 +812,8 @@ JOIN ( repository_id, storage, generation, - repository_assignments.storage IS NOT NULL AS assigned + repository_assignments.storage IS NOT NULL AS assigned, + verified_at FROM storage_repositories FULL JOIN ( SELECT repository_id, storage diff --git a/internal/praefect/datastore/repository_store_test.go b/internal/praefect/datastore/repository_store_test.go index e4dd9ac68..9c980376c 100644 --- a/internal/praefect/datastore/repository_store_test.go +++ b/internal/praefect/datastore/repository_store_test.go @@ -5,6 +5,7 @@ import ( "database/sql" "fmt" "testing" + "time" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" @@ -1176,6 +1177,20 @@ func TestRepositoryStore_incrementGenerationConcurrently(t *testing.T) { func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { t.Parallel() db := testdb.New(t) + + // Truncate the time to millisecond as Postgres returns timestamps with that precision. + now := time.Now().UTC().Truncate(time.Microsecond) + + // Scanning from Postgres doesn't set the UTC location as Go does, just the offset and DST + // information. Convert to UTC so we can verify the time is correct with require.Equal. + replicasAtUTC := func(metadata []RepositoryMetadata) { + for i := range metadata { + for j := range metadata[i].Replicas { + metadata[i].Replicas[j].VerifiedAt = metadata[i].Replicas[j].VerifiedAt.UTC() + } + } + } + for _, tc := range []struct { desc string nonExistentRepository bool @@ -1190,7 +1205,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "all up to date without assignments", existingGenerations: map[string]int{"primary": 0, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, }, }, @@ -1198,7 +1213,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "unconfigured node outdated without assignments", existingGenerations: map[string]int{"primary": 1, "secondary-1": 1, "unconfigured": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, {Storage: "unconfigured", Generation: 0}, }, @@ -1207,7 +1222,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "unconfigured node contains the latest", existingGenerations: map[string]int{"primary": 0, "secondary-1": 0, "unconfigured": 1}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true, Healthy: true}, {Storage: "unconfigured", Generation: 1, Assigned: false}, }, @@ -1217,7 +1232,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "node has no repository without assignments", existingGenerations: map[string]int{"primary": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: -1, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1226,7 +1241,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "node has outdated repository without assignments", existingGenerations: map[string]int{"primary": 1, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1235,7 +1250,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "node with no repository heavily outdated", existingGenerations: map[string]int{"primary": 10}, replicas: []Replica{ - {Storage: "primary", Generation: 10, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 10, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: -1, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1244,7 +1259,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { desc: "node with a heavily outdated repository", existingGenerations: map[string]int{"primary": 10, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 10, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 10, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1259,7 +1274,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary"}, existingGenerations: map[string]int{"primary": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, }, }, { @@ -1267,7 +1282,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary"}, existingGenerations: map[string]int{"primary": 1, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Healthy: true}, }, }, @@ -1276,7 +1291,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "secondary-1"}, existingGenerations: map[string]int{"primary": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: -1, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1286,7 +1301,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "secondary-1"}, existingGenerations: map[string]int{"primary": 1, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true, Healthy: true}, }, hasPartiallyReplicated: true, @@ -1296,7 +1311,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary"}, existingGenerations: map[string]int{"primary": 0, "secondary-1": 1}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 1, Assigned: false, Healthy: true, ValidPrimary: true}, }, hasPartiallyReplicated: true, @@ -1326,7 +1341,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "unconfigured"}, existingGenerations: map[string]int{"primary": 1}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, }, }, { @@ -1334,7 +1349,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "unconfigured"}, existingGenerations: map[string]int{"primary": 1, "unconfigured": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 1, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "unconfigured", Generation: 0, Assigned: false}, }, }, @@ -1355,7 +1370,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "secondary-1"}, existingGenerations: map[string]int{"primary": 0, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true}, + {Storage: "primary", Generation: 0, Assigned: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true}, }, hasPartiallyReplicated: true, @@ -1366,7 +1381,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary"}, existingGenerations: map[string]int{"primary": 0, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true}, + {Storage: "primary", Generation: 0, Assigned: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Healthy: true, ValidPrimary: true}, }, hasPartiallyReplicated: true, @@ -1377,7 +1392,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary"}, existingGenerations: map[string]int{"primary": 0, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0}, }, }, @@ -1387,7 +1402,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { existingAssignments: []string{"primary", "secondary-1"}, existingGenerations: map[string]int{"primary": 0, "secondary-1": 0}, replicas: []Replica{ - {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true}, + {Storage: "primary", Generation: 0, Assigned: true, Healthy: true, ValidPrimary: true, VerifiedAt: now}, {Storage: "secondary-1", Generation: 0, Assigned: true}, }, hasPartiallyReplicated: true, @@ -1440,6 +1455,11 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { require.NoError(t, rs.SetGeneration(ctx, repositoryID, storage, relativePath, generation)) } + // Set the primary always having been verified. This is just to verify the data is correctly + // returned, there's no real logic to test. + _, err = tx.ExecContext(ctx, "UPDATE storage_repositories SET verified_at = $1 WHERE storage = 'primary'", now) + require.NoError(t, err) + for _, storage := range tc.existingAssignments { _, err := tx.ExecContext(ctx, ` INSERT INTO repository_assignments (repository_id, virtual_storage, relative_path, storage) @@ -1472,6 +1492,7 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { partiallyReplicated, err := rs.GetPartiallyAvailableRepositories(ctx, virtualStorage) require.NoError(t, err) + replicasAtUTC(partiallyReplicated) require.Equal(t, expectedPartiallyReplicated, partiallyReplicated) var expectedErr error @@ -1482,10 +1503,12 @@ func TestPostgresRepositoryStore_GetRepositoryMetadata(t *testing.T) { metadata, err := rs.GetRepositoryMetadata(ctx, repositoryID) require.Equal(t, expectedErr, err) + replicasAtUTC([]RepositoryMetadata{metadata}) require.Equal(t, expectedMetadata, metadata) metadata, err = rs.GetRepositoryMetadataByPath(ctx, virtualStorage, relativePath) require.Equal(t, expectedErr, err) + replicasAtUTC([]RepositoryMetadata{metadata}) require.Equal(t, expectedMetadata, metadata) }) } diff --git a/internal/praefect/service/info/metadata.go b/internal/praefect/service/info/metadata.go index d469b94c1..24c716224 100644 --- a/internal/praefect/service/info/metadata.go +++ b/internal/praefect/service/info/metadata.go @@ -8,6 +8,7 @@ import ( "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/commonerr" "gitlab.com/gitlab-org/gitaly/v14/internal/praefect/datastore" "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb" + "google.golang.org/protobuf/types/known/timestamppb" ) // GetRepositoryMetadata returns the cluster metadata for a repository. @@ -37,12 +38,18 @@ func (s *Server) GetRepositoryMetadata(ctx context.Context, req *gitalypb.GetRep replicas := make([]*gitalypb.GetRepositoryMetadataResponse_Replica, 0, len(metadata.Replicas)) for _, replica := range metadata.Replicas { + var verifiedAt *timestamppb.Timestamp + if !replica.VerifiedAt.IsZero() { + verifiedAt = timestamppb.New(replica.VerifiedAt) + } + replicas = append(replicas, &gitalypb.GetRepositoryMetadataResponse_Replica{ Storage: replica.Storage, Assigned: replica.Assigned, Generation: replica.Generation, Healthy: replica.Healthy, ValidPrimary: replica.ValidPrimary, + VerifiedAt: verifiedAt, }) } diff --git a/proto/go/gitalypb/praefect.pb.go b/proto/go/gitalypb/praefect.pb.go index e59dacdf1..62f8af5b8 100644 --- a/proto/go/gitalypb/praefect.pb.go +++ b/proto/go/gitalypb/praefect.pb.go @@ -9,6 +9,7 @@ package gitalypb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -703,6 +704,8 @@ type GetRepositoryMetadataResponse_Replica struct { Healthy bool `protobuf:"varint,5,opt,name=healthy,proto3" json:"healthy,omitempty"` // valid_primary indicates whether the replica is considered a valid primary. ValidPrimary bool `protobuf:"varint,6,opt,name=valid_primary,json=validPrimary,proto3" json:"valid_primary,omitempty"` + // verified_at is the last successful verification time of the replica. + VerifiedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=verified_at,json=verifiedAt,proto3" json:"verified_at,omitempty"` } func (x *GetRepositoryMetadataResponse_Replica) Reset() { @@ -772,6 +775,13 @@ func (x *GetRepositoryMetadataResponse_Replica) GetValidPrimary() bool { return false } +func (x *GetRepositoryMetadataResponse_Replica) GetVerifiedAt() *timestamppb.Timestamp { + if x != nil { + return x.VerifiedAt + } + return nil +} + type DatalossCheckResponse_Repository struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -992,172 +1002,178 @@ var file_praefect_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x70, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x1a, 0x0a, 0x6c, 0x69, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, - 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x1a, 0x54, 0x0a, 0x04, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, - 0x68, 0x42, 0x07, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0xdb, 0x03, 0x0a, 0x1d, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x49, - 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, - 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x08, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x08, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x1a, 0x9e, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x9a, 0x01, 0x0a, 0x1b, 0x53, 0x65, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, - 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, - 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, - 0x61, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x3a, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, + 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xe5, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0c, 0x72, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x69, 0x74, 0x61, + 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, + 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x1a, 0x54, 0x0a, 0x04, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x33, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x14, 0x44, - 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, - 0x72, 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x1c, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, - 0x79, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1a, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, - 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22, 0xbb, - 0x03, 0x0a, 0x15, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x1a, 0xd3, 0x02, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, - 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x08, 0x73, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, + 0x74, 0x68, 0x42, 0x07, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x98, 0x04, 0x0a, 0x1d, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x50, + 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1e, 0x0a, + 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, + 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x52, 0x08, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x1a, 0xdb, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3b, 0x0a, 0x0b, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x69, 0x65, 0x64, 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, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x41, 0x74, 0x22, 0x9a, 0x01, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, + 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x2d, 0x0a, 0x12, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x11, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x22, 0x3a, 0x0a, 0x1c, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x22, + 0xa3, 0x01, 0x0a, 0x1e, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, + 0x74, 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x33, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x14, 0x44, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, + 0x75, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x6c, 0x79, 0x5f, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x1a, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x6c, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x64, 0x22, 0xbb, 0x03, 0x0a, + 0x15, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x08, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x61, 0x76, - 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, - 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x5f, 0x62, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x42, - 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x4f, 0x0a, 0x19, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xa3, 0x02, - 0x0a, 0x1a, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, - 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x50, 0x0a, 0x08, - 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x1a, 0x63, - 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, - 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x73, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x73, 0x75, 0x6d, 0x32, 0xfb, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, - 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x12, 0x52, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x73, 0x12, 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0c, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x65, 0x73, 0x1a, 0xd3, 0x02, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x4c, 0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x08, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x1a, 0x95, 0x01, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x5f, 0x62, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x62, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x42, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x68, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x4f, 0x0a, 0x19, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61, - 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x22, 0xa3, 0x02, 0x0a, 0x1a, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x69, + 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x50, 0x0a, 0x08, 0x72, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x1a, 0x63, 0x0a, 0x11, + 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x73, 0x12, 0x32, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, + 0x6d, 0x32, 0xfb, 0x03, 0x0a, 0x13, 0x50, 0x72, 0x61, 0x65, 0x66, 0x65, 0x63, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x12, 0x52, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, + 0x21, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x52, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, + 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, - 0x65, 0x12, 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, - 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, - 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x61, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x2e, 0x67, 0x69, 0x74, - 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x24, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, - 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, - 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, - 0x79, 0x2f, 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, - 0x69, 0x74, 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x44, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, + 0x26, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, + 0x2e, 0x53, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x61, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, + 0x79, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x53, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x2e, 0x67, + 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x04, 0xf0, 0x97, 0x28, 0x01, 0x42, + 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x69, + 0x74, 0x6c, 0x61, 0x62, 0x2d, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x79, 0x2f, + 0x76, 0x31, 0x34, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x79, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1190,6 +1206,7 @@ var file_praefect_proto_goTypes = []interface{}{ (*DatalossCheckResponse_Repository_Storage)(nil), // 13: gitaly.DatalossCheckResponse.Repository.Storage (*RepositoryReplicasResponse_RepositoryDetails)(nil), // 14: gitaly.RepositoryReplicasResponse.RepositoryDetails (*Repository)(nil), // 15: gitaly.Repository + (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp } var file_praefect_proto_depIdxs = []int32{ 10, // 0: gitaly.GetRepositoryMetadataRequest.path:type_name -> gitaly.GetRepositoryMetadataRequest.Path @@ -1198,23 +1215,24 @@ var file_praefect_proto_depIdxs = []int32{ 15, // 3: gitaly.RepositoryReplicasRequest.repository:type_name -> gitaly.Repository 14, // 4: gitaly.RepositoryReplicasResponse.primary:type_name -> gitaly.RepositoryReplicasResponse.RepositoryDetails 14, // 5: gitaly.RepositoryReplicasResponse.replicas:type_name -> gitaly.RepositoryReplicasResponse.RepositoryDetails - 13, // 6: gitaly.DatalossCheckResponse.Repository.storages:type_name -> gitaly.DatalossCheckResponse.Repository.Storage - 15, // 7: gitaly.RepositoryReplicasResponse.RepositoryDetails.repository:type_name -> gitaly.Repository - 8, // 8: gitaly.PraefectInfoService.RepositoryReplicas:input_type -> gitaly.RepositoryReplicasRequest - 6, // 9: gitaly.PraefectInfoService.DatalossCheck:input_type -> gitaly.DatalossCheckRequest - 4, // 10: gitaly.PraefectInfoService.SetAuthoritativeStorage:input_type -> gitaly.SetAuthoritativeStorageRequest - 2, // 11: gitaly.PraefectInfoService.SetReplicationFactor:input_type -> gitaly.SetReplicationFactorRequest - 0, // 12: gitaly.PraefectInfoService.GetRepositoryMetadata:input_type -> gitaly.GetRepositoryMetadataRequest - 9, // 13: gitaly.PraefectInfoService.RepositoryReplicas:output_type -> gitaly.RepositoryReplicasResponse - 7, // 14: gitaly.PraefectInfoService.DatalossCheck:output_type -> gitaly.DatalossCheckResponse - 5, // 15: gitaly.PraefectInfoService.SetAuthoritativeStorage:output_type -> gitaly.SetAuthoritativeStorageResponse - 3, // 16: gitaly.PraefectInfoService.SetReplicationFactor:output_type -> gitaly.SetReplicationFactorResponse - 1, // 17: gitaly.PraefectInfoService.GetRepositoryMetadata:output_type -> gitaly.GetRepositoryMetadataResponse - 13, // [13:18] is the sub-list for method output_type - 8, // [8:13] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 16, // 6: gitaly.GetRepositoryMetadataResponse.Replica.verified_at:type_name -> google.protobuf.Timestamp + 13, // 7: gitaly.DatalossCheckResponse.Repository.storages:type_name -> gitaly.DatalossCheckResponse.Repository.Storage + 15, // 8: gitaly.RepositoryReplicasResponse.RepositoryDetails.repository:type_name -> gitaly.Repository + 8, // 9: gitaly.PraefectInfoService.RepositoryReplicas:input_type -> gitaly.RepositoryReplicasRequest + 6, // 10: gitaly.PraefectInfoService.DatalossCheck:input_type -> gitaly.DatalossCheckRequest + 4, // 11: gitaly.PraefectInfoService.SetAuthoritativeStorage:input_type -> gitaly.SetAuthoritativeStorageRequest + 2, // 12: gitaly.PraefectInfoService.SetReplicationFactor:input_type -> gitaly.SetReplicationFactorRequest + 0, // 13: gitaly.PraefectInfoService.GetRepositoryMetadata:input_type -> gitaly.GetRepositoryMetadataRequest + 9, // 14: gitaly.PraefectInfoService.RepositoryReplicas:output_type -> gitaly.RepositoryReplicasResponse + 7, // 15: gitaly.PraefectInfoService.DatalossCheck:output_type -> gitaly.DatalossCheckResponse + 5, // 16: gitaly.PraefectInfoService.SetAuthoritativeStorage:output_type -> gitaly.SetAuthoritativeStorageResponse + 3, // 17: gitaly.PraefectInfoService.SetReplicationFactor:output_type -> gitaly.SetReplicationFactorResponse + 1, // 18: gitaly.PraefectInfoService.GetRepositoryMetadata:output_type -> gitaly.GetRepositoryMetadataResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_praefect_proto_init() } diff --git a/proto/praefect.proto b/proto/praefect.proto index 34a4c5f79..c26a22c20 100644 --- a/proto/praefect.proto +++ b/proto/praefect.proto @@ -6,6 +6,7 @@ option go_package = "gitlab.com/gitlab-org/gitaly/v14/proto/go/gitalypb"; import "lint.proto"; import "shared.proto"; +import "google/protobuf/timestamp.proto"; service PraefectInfoService { option (intercepted) = true; @@ -64,6 +65,8 @@ message GetRepositoryMetadataResponse { bool healthy = 5; // valid_primary indicates whether the replica is considered a valid primary. bool valid_primary = 6; + // verified_at is the last successful verification time of the replica. + google.protobuf.Timestamp verified_at = 7; } // repository_id is the internal ID of the repository. diff --git a/ruby/proto/gitaly/praefect_pb.rb b/ruby/proto/gitaly/praefect_pb.rb index 4ce78f789..918674133 100644 --- a/ruby/proto/gitaly/praefect_pb.rb +++ b/ruby/proto/gitaly/praefect_pb.rb @@ -3,6 +3,7 @@ require 'lint_pb' require 'shared_pb' +require 'google/protobuf/timestamp_pb' require 'google/protobuf' Google::Protobuf::DescriptorPool.generated_pool.build do @@ -32,6 +33,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :generation, :int64, 4 optional :healthy, :bool, 5 optional :valid_primary, :bool, 6 + optional :verified_at, :message, 7, "google.protobuf.Timestamp" end add_message "gitaly.SetReplicationFactorRequest" do optional :virtual_storage, :string, 1 |