From 59344074433b6c6f517441d0dc1695f2e5c675b7 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Sat, 12 Nov 2022 11:36:18 -0800 Subject: [PATCH] Storage: add an admin write flavor that can explicitly set the user/time (#58618) --- pkg/services/export/object_store.go | 44 +- .../sqlstore/migrations/object_store_mig.go | 8 +- .../store/object/dummy/dummy_server.go | 17 +- pkg/services/store/object/dummy/fake_store.go | 8 + pkg/services/store/object/json.go | 12 +- pkg/services/store/object/object.pb.go | 750 +++++++++++------- pkg/services/store/object/object.proto | 61 +- pkg/services/store/object/object_grpc.pb.go | 122 +++ .../object/sqlstash/sql_storage_server.go | 179 +++-- pkg/services/store/object/utils.go | 11 + 10 files changed, 844 insertions(+), 368 deletions(-) create mode 100644 pkg/services/store/object/utils.go diff --git a/pkg/services/export/object_store.go b/pkg/services/export/object_store.go index 1b902e64589..10d3ec96719 100644 --- a/pkg/services/export/object_store.go +++ b/pkg/services/export/object_store.go @@ -123,14 +123,21 @@ func (e *objectStoreJob) start(ctx context.Context) { rowUser.UserID = 0 // avoid Uint64Val issue???? } - _, err = e.store.Write(ctx, &object.WriteObjectRequest{ + _, err = e.store.AdminWrite(ctx, &object.AdminWriteObjectRequest{ GRN: &object.GRN{ Scope: models.ObjectStoreScopeEntity, UID: dash.UID, Kind: models.StandardKindDashboard, }, - Body: dash.Body, - Comment: "export from dashboard table", + ClearHistory: true, + Version: fmt.Sprintf("%d", dash.Version), + CreatedAt: dash.Created.UnixMilli(), + UpdatedAt: dash.Updated.UnixMilli(), + UpdatedBy: fmt.Sprintf("user:%d", dash.UpdatedBy), + CreatedBy: fmt.Sprintf("user:%d", dash.CreatedBy), + Origin: "export-from-sql", + Body: dash.Data, + Comment: "(exported from SQL)", }) if err != nil { e.status.Status = "error: " + err.Error() @@ -254,34 +261,25 @@ func (e *objectStoreJob) start(ctx context.Context) { } type dashInfo struct { - OrgID int64 + OrgID int64 `db:"org_id"` UID string - Body []byte - UpdatedBy int64 + Version int64 + Slug string + Data []byte + Created time.Time + Updated time.Time + CreatedBy int64 `db:"created_by"` + UpdatedBy int64 `db:"updated_by"` } +// TODO, paging etc func (e *objectStoreJob) getDashboards(ctx context.Context) ([]dashInfo, error) { e.status.Last = "find dashbaords...." e.broadcaster(e.status) dash := make([]dashInfo, 0) - rows, err := e.sess.Query(ctx, "SELECT org_id,uid,data,updated_by FROM dashboard WHERE is_folder=false") - if err != nil { - return nil, err - } - for rows.Next() { - if e.stopRequested { - return dash, nil - } - - row := dashInfo{} - err = rows.Scan(&row.OrgID, &row.UID, &row.Body, &row.UpdatedBy) - if err != nil { - return nil, err - } - dash = append(dash, row) - } - return dash, nil + err := e.sess.Select(ctx, &dash, "SELECT org_id,uid,version,slug,data,created,updated,created_by,updated_by FROM dashboard WHERE is_folder=false") + return dash, err } func (e *objectStoreJob) getStatus() ExportStatus { diff --git a/pkg/services/sqlstore/migrations/object_store_mig.go b/pkg/services/sqlstore/migrations/object_store_mig.go index f2053e33407..6f87b1d6265 100644 --- a/pkg/services/sqlstore/migrations/object_store_mig.go +++ b/pkg/services/sqlstore/migrations/object_store_mig.go @@ -46,9 +46,9 @@ func addObjectStorageMigrations(mg *migrator.Migrator) { {Name: "updated_by", Type: migrator.DB_NVarchar, Length: 190, Nullable: false}, {Name: "created_by", Type: migrator.DB_NVarchar, Length: 190, Nullable: false}, - // For objects that are synchronized from an external source (ie provisioning or git) - {Name: "sync_src", Type: migrator.DB_Text, Nullable: true}, - {Name: "sync_time", Type: migrator.DB_BigInt, Nullable: true}, + // Mark objects with origin metadata + {Name: "origin", Type: migrator.DB_Text, Nullable: true}, + {Name: "origin_ts", Type: migrator.DB_BigInt, Nullable: false}, // Summary data (always extracted from the `body` column) {Name: "name", Type: migrator.DB_NVarchar, Length: 255, Nullable: false}, @@ -134,7 +134,7 @@ func addObjectStorageMigrations(mg *migrator.Migrator) { // Migration cleanups: given that this is a complex setup // that requires a lot of testing before we are ready to push out of dev // this script lets us easy wipe previous changes and initialize clean tables - suffix := " (v2)" // change this when we want to wipe and reset the object tables + suffix := " (v5)" // change this when we want to wipe and reset the object tables mg.AddMigration("ObjectStore init: cleanup"+suffix, migrator.NewRawSQLMigration(strings.TrimSpace(` DELETE FROM migration_log WHERE migration_id LIKE 'ObjectStore init%'; `))) diff --git a/pkg/services/store/object/dummy/dummy_server.go b/pkg/services/store/object/dummy/dummy_server.go index 323f7b49082..4e5fbe6f721 100644 --- a/pkg/services/store/object/dummy/dummy_server.go +++ b/pkg/services/store/object/dummy/dummy_server.go @@ -35,6 +35,10 @@ var ( rawObjectVersion = 9 ) +// Make sure we implement both store + admin +var _ object.ObjectStoreServer = &dummyObjectServer{} +var _ object.ObjectStoreAdminServer = &dummyObjectServer{} + func ProvideDummyObjectServer(cfg *setting.Cfg, grpcServerProvider grpcserver.Provider, kinds kind.KindRegistry) object.ObjectStoreServer { objectServer := &dummyObjectServer{ collection: persistentcollection.NewLocalFSPersistentCollection[*RawObjectWithHistory]("raw-object", cfg.DataPath, rawObjectVersion), @@ -149,7 +153,7 @@ func createContentsHash(contents []byte) string { return hex.EncodeToString(hash[:]) } -func (i *dummyObjectServer) update(ctx context.Context, r *object.WriteObjectRequest, namespace string) (*object.WriteObjectResponse, error) { +func (i *dummyObjectServer) update(ctx context.Context, r *object.AdminWriteObjectRequest, namespace string) (*object.WriteObjectResponse, error) { builder := i.kinds.GetSummaryBuilder(r.GRN.Kind) if builder == nil { return nil, fmt.Errorf("unsupported kind: " + r.GRN.Kind) @@ -222,7 +226,7 @@ func (i *dummyObjectServer) update(ctx context.Context, r *object.WriteObjectReq return rsp, nil } -func (i *dummyObjectServer) insert(ctx context.Context, r *object.WriteObjectRequest, namespace string) (*object.WriteObjectResponse, error) { +func (i *dummyObjectServer) insert(ctx context.Context, r *object.AdminWriteObjectRequest, namespace string) (*object.WriteObjectResponse, error) { modifier := store.GetUserIDString(store.UserFromContext(ctx)) rawObj := &object.RawObject{ GRN: r.GRN, @@ -266,6 +270,15 @@ func (i *dummyObjectServer) insert(ctx context.Context, r *object.WriteObjectReq } func (i *dummyObjectServer) Write(ctx context.Context, r *object.WriteObjectRequest) (*object.WriteObjectResponse, error) { + return i.doWrite(ctx, object.ToAdminWriteObjectRequest(r)) +} + +func (i *dummyObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteObjectRequest) (*object.WriteObjectResponse, error) { + // Check permissions? + return i.doWrite(ctx, r) +} + +func (i *dummyObjectServer) doWrite(ctx context.Context, r *object.AdminWriteObjectRequest) (*object.WriteObjectResponse, error) { grn := getFullGRN(ctx, r.GRN) namespace := namespaceFromUID(grn) obj, err := i.collection.FindFirst(ctx, namespace, func(i *RawObjectWithHistory) (bool, error) { diff --git a/pkg/services/store/object/dummy/fake_store.go b/pkg/services/store/object/dummy/fake_store.go index 092f4ce9f43..c85c56ebd68 100644 --- a/pkg/services/store/object/dummy/fake_store.go +++ b/pkg/services/store/object/dummy/fake_store.go @@ -7,12 +7,20 @@ import ( "github.com/grafana/grafana/pkg/services/store/object" ) +// Make sure we implement both store + admin +var _ object.ObjectStoreServer = &fakeObjectStore{} +var _ object.ObjectStoreAdminServer = &fakeObjectStore{} + func ProvideFakeObjectServer() object.ObjectStoreServer { return &fakeObjectStore{} } type fakeObjectStore struct{} +func (i fakeObjectStore) AdminWrite(ctx context.Context, r *object.AdminWriteObjectRequest) (*object.WriteObjectResponse, error) { + return nil, fmt.Errorf("unimplemented") +} + func (i fakeObjectStore) Write(ctx context.Context, r *object.WriteObjectRequest) (*object.WriteObjectResponse, error) { return nil, fmt.Errorf("unimplemented") } diff --git a/pkg/services/store/object/json.go b/pkg/services/store/object/json.go index 45b9995bfa4..b3c4e20d839 100644 --- a/pkg/services/store/object/json.go +++ b/pkg/services/store/object/json.go @@ -102,10 +102,10 @@ func (codec *rawObjectCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) stream.WriteInt64(obj.Size) } - if obj.Sync != nil { + if obj.Origin != nil { stream.WriteMore() - stream.WriteObjectField("sync") - stream.WriteVal(obj.Sync) + stream.WriteObjectField("origin") + stream.WriteVal(obj.Origin) } stream.WriteObjectEnd() @@ -137,9 +137,9 @@ func readRawObject(iter *jsoniter.Iterator, raw *RawObject) { raw.ETag = iter.ReadString() case "version": raw.Version = iter.ReadString() - case "sync": - raw.Sync = &RawObjectSyncInfo{} - iter.ReadVal(raw.Sync) + case "origin": + raw.Origin = &ObjectOriginInfo{} + iter.ReadVal(raw.Origin) case "body": var val interface{} diff --git a/pkg/services/store/object/object.pb.go b/pkg/services/store/object/object.pb.go index 78248fedb08..b37ab17330d 100644 --- a/pkg/services/store/object/object.pb.go +++ b/pkg/services/store/object/object.pb.go @@ -70,7 +70,7 @@ func (x WriteObjectResponse_Status) Number() protoreflect.EnumNumber { // Deprecated: Use WriteObjectResponse_Status.Descriptor instead. func (WriteObjectResponse_Status) EnumDescriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{10, 0} + return file_object_proto_rawDescGZIP(), []int{11, 0} } type GRN struct { @@ -179,7 +179,7 @@ type RawObject struct { // NOTE: currently managed by the dashboard+dashboard_version tables Version string `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"` // External location info - Sync *RawObjectSyncInfo `protobuf:"bytes,10,opt,name=sync,proto3" json:"sync,omitempty"` + Origin *ObjectOriginInfo `protobuf:"bytes,10,opt,name=origin,proto3" json:"origin,omitempty"` } func (x *RawObject) Reset() { @@ -277,14 +277,14 @@ func (x *RawObject) GetVersion() string { return "" } -func (x *RawObject) GetSync() *RawObjectSyncInfo { +func (x *RawObject) GetOrigin() *ObjectOriginInfo { if x != nil { - return x.Sync + return x.Origin } return nil } -type RawObjectSyncInfo struct { +type ObjectOriginInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -295,8 +295,8 @@ type RawObjectSyncInfo struct { Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"` } -func (x *RawObjectSyncInfo) Reset() { - *x = RawObjectSyncInfo{} +func (x *ObjectOriginInfo) Reset() { + *x = ObjectOriginInfo{} if protoimpl.UnsafeEnabled { mi := &file_object_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -304,13 +304,13 @@ func (x *RawObjectSyncInfo) Reset() { } } -func (x *RawObjectSyncInfo) String() string { +func (x *ObjectOriginInfo) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RawObjectSyncInfo) ProtoMessage() {} +func (*ObjectOriginInfo) ProtoMessage() {} -func (x *RawObjectSyncInfo) ProtoReflect() protoreflect.Message { +func (x *ObjectOriginInfo) ProtoReflect() protoreflect.Message { mi := &file_object_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -322,19 +322,19 @@ func (x *RawObjectSyncInfo) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RawObjectSyncInfo.ProtoReflect.Descriptor instead. -func (*RawObjectSyncInfo) Descriptor() ([]byte, []int) { +// Deprecated: Use ObjectOriginInfo.ProtoReflect.Descriptor instead. +func (*ObjectOriginInfo) Descriptor() ([]byte, []int) { return file_object_proto_rawDescGZIP(), []int{2} } -func (x *RawObjectSyncInfo) GetSource() string { +func (x *ObjectOriginInfo) GetSource() string { if x != nil { return x.Source } return "" } -func (x *RawObjectSyncInfo) GetTime() int64 { +func (x *ObjectOriginInfo) GetTime() int64 { if x != nil { return x.Time } @@ -806,6 +806,154 @@ func (x *WriteObjectRequest) GetPreviousVersion() string { return "" } +// This operation is useful when syncing a resource from external sources +// that have more accurate metadata information (git, or an archive). +// This process can bypass the forced checks that +type AdminWriteObjectRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Object identifier + GRN *GRN `protobuf:"bytes,1,opt,name=GRN,proto3" json:"GRN,omitempty"` + // The raw object body + Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` + // Message that can be seen when exploring object history + Comment string `protobuf:"bytes,3,opt,name=comment,proto3" json:"comment,omitempty"` + // Time in epoch milliseconds that the object was created + // Optional, if 0 it will use the current time + CreatedAt int64 `protobuf:"varint,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + // Time in epoch milliseconds that the object was updated + // Optional, if empty it will use the current user + UpdatedAt int64 `protobuf:"varint,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + // Who created the object + // Optional, if 0 it will use the current time + CreatedBy string `protobuf:"bytes,6,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + // Who updated the object + // Optional, if empty it will use the current user + UpdatedBy string `protobuf:"bytes,7,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"` + // An explicit version identifier + // Optional, if set, this will overwrite/define an explicit version + Version string `protobuf:"bytes,8,opt,name=version,proto3" json:"version,omitempty"` + // Used for optimistic locking. If missing, the previous version will be replaced regardless + // This may not be used along with an explicit version in the request + PreviousVersion string `protobuf:"bytes,9,opt,name=previous_version,json=previousVersion,proto3" json:"previous_version,omitempty"` + // Request that all previous versions are removed from the history + // This will make sense for systems that manage history explicitly externallay + ClearHistory bool `protobuf:"varint,10,opt,name=clear_history,json=clearHistory,proto3" json:"clear_history,omitempty"` + // Optionally define where the object came from + Origin string `protobuf:"bytes,11,opt,name=origin,proto3" json:"origin,omitempty"` +} + +func (x *AdminWriteObjectRequest) Reset() { + *x = AdminWriteObjectRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_object_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdminWriteObjectRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdminWriteObjectRequest) ProtoMessage() {} + +func (x *AdminWriteObjectRequest) ProtoReflect() protoreflect.Message { + mi := &file_object_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdminWriteObjectRequest.ProtoReflect.Descriptor instead. +func (*AdminWriteObjectRequest) Descriptor() ([]byte, []int) { + return file_object_proto_rawDescGZIP(), []int{10} +} + +func (x *AdminWriteObjectRequest) GetGRN() *GRN { + if x != nil { + return x.GRN + } + return nil +} + +func (x *AdminWriteObjectRequest) GetBody() []byte { + if x != nil { + return x.Body + } + return nil +} + +func (x *AdminWriteObjectRequest) GetComment() string { + if x != nil { + return x.Comment + } + return "" +} + +func (x *AdminWriteObjectRequest) GetCreatedAt() int64 { + if x != nil { + return x.CreatedAt + } + return 0 +} + +func (x *AdminWriteObjectRequest) GetUpdatedAt() int64 { + if x != nil { + return x.UpdatedAt + } + return 0 +} + +func (x *AdminWriteObjectRequest) GetCreatedBy() string { + if x != nil { + return x.CreatedBy + } + return "" +} + +func (x *AdminWriteObjectRequest) GetUpdatedBy() string { + if x != nil { + return x.UpdatedBy + } + return "" +} + +func (x *AdminWriteObjectRequest) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *AdminWriteObjectRequest) GetPreviousVersion() string { + if x != nil { + return x.PreviousVersion + } + return "" +} + +func (x *AdminWriteObjectRequest) GetClearHistory() bool { + if x != nil { + return x.ClearHistory + } + return false +} + +func (x *AdminWriteObjectRequest) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + type WriteObjectResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -826,7 +974,7 @@ type WriteObjectResponse struct { func (x *WriteObjectResponse) Reset() { *x = WriteObjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[10] + mi := &file_object_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -839,7 +987,7 @@ func (x *WriteObjectResponse) String() string { func (*WriteObjectResponse) ProtoMessage() {} func (x *WriteObjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[10] + mi := &file_object_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -852,7 +1000,7 @@ func (x *WriteObjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WriteObjectResponse.ProtoReflect.Descriptor instead. func (*WriteObjectResponse) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{10} + return file_object_proto_rawDescGZIP(), []int{11} } func (x *WriteObjectResponse) GetError() *ObjectErrorInfo { @@ -904,7 +1052,7 @@ type DeleteObjectRequest struct { func (x *DeleteObjectRequest) Reset() { *x = DeleteObjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[11] + mi := &file_object_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -917,7 +1065,7 @@ func (x *DeleteObjectRequest) String() string { func (*DeleteObjectRequest) ProtoMessage() {} func (x *DeleteObjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[11] + mi := &file_object_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -930,7 +1078,7 @@ func (x *DeleteObjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteObjectRequest.ProtoReflect.Descriptor instead. func (*DeleteObjectRequest) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{11} + return file_object_proto_rawDescGZIP(), []int{12} } func (x *DeleteObjectRequest) GetGRN() *GRN { @@ -958,7 +1106,7 @@ type DeleteObjectResponse struct { func (x *DeleteObjectResponse) Reset() { *x = DeleteObjectResponse{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[12] + mi := &file_object_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -971,7 +1119,7 @@ func (x *DeleteObjectResponse) String() string { func (*DeleteObjectResponse) ProtoMessage() {} func (x *DeleteObjectResponse) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[12] + mi := &file_object_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -984,7 +1132,7 @@ func (x *DeleteObjectResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteObjectResponse.ProtoReflect.Descriptor instead. func (*DeleteObjectResponse) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{12} + return file_object_proto_rawDescGZIP(), []int{13} } func (x *DeleteObjectResponse) GetOK() bool { @@ -1010,7 +1158,7 @@ type ObjectHistoryRequest struct { func (x *ObjectHistoryRequest) Reset() { *x = ObjectHistoryRequest{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[13] + mi := &file_object_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1023,7 +1171,7 @@ func (x *ObjectHistoryRequest) String() string { func (*ObjectHistoryRequest) ProtoMessage() {} func (x *ObjectHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[13] + mi := &file_object_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1036,7 +1184,7 @@ func (x *ObjectHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectHistoryRequest.ProtoReflect.Descriptor instead. func (*ObjectHistoryRequest) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{13} + return file_object_proto_rawDescGZIP(), []int{14} } func (x *ObjectHistoryRequest) GetGRN() *GRN { @@ -1076,7 +1224,7 @@ type ObjectHistoryResponse struct { func (x *ObjectHistoryResponse) Reset() { *x = ObjectHistoryResponse{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[14] + mi := &file_object_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1089,7 +1237,7 @@ func (x *ObjectHistoryResponse) String() string { func (*ObjectHistoryResponse) ProtoMessage() {} func (x *ObjectHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[14] + mi := &file_object_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1102,7 +1250,7 @@ func (x *ObjectHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectHistoryResponse.ProtoReflect.Descriptor instead. func (*ObjectHistoryResponse) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{14} + return file_object_proto_rawDescGZIP(), []int{15} } func (x *ObjectHistoryResponse) GetGRN() *GRN { @@ -1156,7 +1304,7 @@ type ObjectSearchRequest struct { func (x *ObjectSearchRequest) Reset() { *x = ObjectSearchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[15] + mi := &file_object_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1169,7 +1317,7 @@ func (x *ObjectSearchRequest) String() string { func (*ObjectSearchRequest) ProtoMessage() {} func (x *ObjectSearchRequest) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[15] + mi := &file_object_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1182,7 +1330,7 @@ func (x *ObjectSearchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectSearchRequest.ProtoReflect.Descriptor instead. func (*ObjectSearchRequest) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{15} + return file_object_proto_rawDescGZIP(), []int{16} } func (x *ObjectSearchRequest) GetNextPageToken() string { @@ -1288,7 +1436,7 @@ type ObjectSearchResult struct { func (x *ObjectSearchResult) Reset() { *x = ObjectSearchResult{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[16] + mi := &file_object_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1301,7 +1449,7 @@ func (x *ObjectSearchResult) String() string { func (*ObjectSearchResult) ProtoMessage() {} func (x *ObjectSearchResult) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[16] + mi := &file_object_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1314,7 +1462,7 @@ func (x *ObjectSearchResult) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectSearchResult.ProtoReflect.Descriptor instead. func (*ObjectSearchResult) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{16} + return file_object_proto_rawDescGZIP(), []int{17} } func (x *ObjectSearchResult) GetGRN() *GRN { @@ -1407,7 +1555,7 @@ type ObjectSearchResponse struct { func (x *ObjectSearchResponse) Reset() { *x = ObjectSearchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_object_proto_msgTypes[17] + mi := &file_object_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1420,7 +1568,7 @@ func (x *ObjectSearchResponse) String() string { func (*ObjectSearchResponse) ProtoMessage() {} func (x *ObjectSearchResponse) ProtoReflect() protoreflect.Message { - mi := &file_object_proto_msgTypes[17] + mi := &file_object_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1433,7 +1581,7 @@ func (x *ObjectSearchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ObjectSearchResponse.ProtoReflect.Descriptor instead. func (*ObjectSearchResponse) Descriptor() ([]byte, []int) { - return file_object_proto_rawDescGZIP(), []int{17} + return file_object_proto_rawDescGZIP(), []int{18} } func (x *ObjectSearchResponse) GetResults() []*ObjectSearchResult { @@ -1460,7 +1608,7 @@ var file_object_proto_rawDesc = []byte{ 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x22, 0xab, 0x02, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x4f, 0x62, + 0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, @@ -1476,196 +1624,230 @@ var file_object_proto_rawDesc = []byte{ 0x09, 0x52, 0x04, 0x45, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x04, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x61, 0x77, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, - 0x73, 0x79, 0x6e, 0x63, 0x22, 0x3f, 0x0a, 0x11, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x0f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x11, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x45, - 0x54, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61, 0x67, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x11, 0x52, 0x65, - 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x18, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, 0x74, 0x68, - 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, - 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x73, 0x75, - 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x69, 0x74, - 0x68, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x62, 0x0a, 0x12, 0x52, 0x65, 0x61, 0x64, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, - 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x49, 0x0a, 0x16, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x22, 0x4f, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, - 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x12, - 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, - 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x10, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0x3e, 0x0a, 0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x0f, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x11, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x45, 0x54, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61, + 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x11, + 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, + 0x74, 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, + 0x69, 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x5f, + 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, + 0x69, 0x74, 0x68, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x62, 0x0a, 0x12, 0x52, 0x65, + 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x29, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x49, + 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x22, 0x4f, 0x0a, 0x17, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, + 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, + 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x29, + 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe4, 0x02, 0x0a, 0x17, 0x41, 0x64, + 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, + 0x03, 0x47, 0x52, 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, + 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, + 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x68, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x22, 0xb3, 0x02, 0x0a, 0x13, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, + 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x6d, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x43, 0x48, 0x41, + 0x4e, 0x47, 0x45, 0x44, 0x10, 0x03, 0x22, 0x5f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xb3, 0x02, 0x0a, 0x13, 0x57, 0x72, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2d, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, - 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x31, 0x0a, - 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, - 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, - 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0d, - 0x0a, 0x09, 0x55, 0x4e, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x03, 0x22, 0x5f, 0x0a, - 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, - 0x47, 0x52, 0x4e, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, - 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26, - 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x4b, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x02, 0x4f, 0x4b, 0x22, 0x73, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0e, 0x0a, 0x02, 0x4f, 0x4b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x4f, 0x4b, 0x22, + 0x73, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, + 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0f, + 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x15, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x14, 0x0a, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, - 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, - 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x15, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, - 0x03, 0x47, 0x52, 0x4e, 0x12, 0x35, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, - 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0x84, 0x03, 0x0a, 0x13, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, - 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, - 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x73, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, - 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1f, 0x0a, - 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, - 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, + 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x35, 0x0a, + 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x84, 0x03, 0x0a, + 0x13, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, 0x74, + 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, + 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, 0x74, + 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, + 0x74, 0x68, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xa4, 0x03, 0x0a, 0x12, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, + 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x07, 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, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x3e, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x26, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, + 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x4a, 0x73, 0x6f, 0x6e, + 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa4, 0x03, 0x0a, 0x12, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, - 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, - 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, - 0x62, 0x6f, 0x64, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x74, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, - 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xae, 0x03, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, - 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, - 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x48, - 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, 0x2e, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x3b, 0x6f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, 0x14, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x32, 0xfa, 0x03, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0x12, 0x3d, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, + 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x4c, 0x0a, 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, + 0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, + 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x43, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, + 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x1f, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x5e, 0x0a, + 0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6d, 0x69, + 0x6e, 0x12, 0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, + 0x1f, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a, + 0x09, 0x2e, 0x2f, 0x3b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -1681,12 +1863,12 @@ func file_object_proto_rawDescGZIP() []byte { } var file_object_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_object_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_object_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_object_proto_goTypes = []interface{}{ (WriteObjectResponse_Status)(0), // 0: object.WriteObjectResponse.Status (*GRN)(nil), // 1: object.GRN (*RawObject)(nil), // 2: object.RawObject - (*RawObjectSyncInfo)(nil), // 3: object.RawObjectSyncInfo + (*ObjectOriginInfo)(nil), // 3: object.ObjectOriginInfo (*ObjectErrorInfo)(nil), // 4: object.ObjectErrorInfo (*ObjectVersionInfo)(nil), // 5: object.ObjectVersionInfo (*ReadObjectRequest)(nil), // 6: object.ReadObjectRequest @@ -1694,54 +1876,60 @@ var file_object_proto_goTypes = []interface{}{ (*BatchReadObjectRequest)(nil), // 8: object.BatchReadObjectRequest (*BatchReadObjectResponse)(nil), // 9: object.BatchReadObjectResponse (*WriteObjectRequest)(nil), // 10: object.WriteObjectRequest - (*WriteObjectResponse)(nil), // 11: object.WriteObjectResponse - (*DeleteObjectRequest)(nil), // 12: object.DeleteObjectRequest - (*DeleteObjectResponse)(nil), // 13: object.DeleteObjectResponse - (*ObjectHistoryRequest)(nil), // 14: object.ObjectHistoryRequest - (*ObjectHistoryResponse)(nil), // 15: object.ObjectHistoryResponse - (*ObjectSearchRequest)(nil), // 16: object.ObjectSearchRequest - (*ObjectSearchResult)(nil), // 17: object.ObjectSearchResult - (*ObjectSearchResponse)(nil), // 18: object.ObjectSearchResponse - nil, // 19: object.ObjectSearchRequest.LabelsEntry - nil, // 20: object.ObjectSearchResult.LabelsEntry + (*AdminWriteObjectRequest)(nil), // 11: object.AdminWriteObjectRequest + (*WriteObjectResponse)(nil), // 12: object.WriteObjectResponse + (*DeleteObjectRequest)(nil), // 13: object.DeleteObjectRequest + (*DeleteObjectResponse)(nil), // 14: object.DeleteObjectResponse + (*ObjectHistoryRequest)(nil), // 15: object.ObjectHistoryRequest + (*ObjectHistoryResponse)(nil), // 16: object.ObjectHistoryResponse + (*ObjectSearchRequest)(nil), // 17: object.ObjectSearchRequest + (*ObjectSearchResult)(nil), // 18: object.ObjectSearchResult + (*ObjectSearchResponse)(nil), // 19: object.ObjectSearchResponse + nil, // 20: object.ObjectSearchRequest.LabelsEntry + nil, // 21: object.ObjectSearchResult.LabelsEntry } var file_object_proto_depIdxs = []int32{ 1, // 0: object.RawObject.GRN:type_name -> object.GRN - 3, // 1: object.RawObject.sync:type_name -> object.RawObjectSyncInfo + 3, // 1: object.RawObject.origin:type_name -> object.ObjectOriginInfo 1, // 2: object.ReadObjectRequest.GRN:type_name -> object.GRN 2, // 3: object.ReadObjectResponse.object:type_name -> object.RawObject 6, // 4: object.BatchReadObjectRequest.batch:type_name -> object.ReadObjectRequest 7, // 5: object.BatchReadObjectResponse.results:type_name -> object.ReadObjectResponse 1, // 6: object.WriteObjectRequest.GRN:type_name -> object.GRN - 4, // 7: object.WriteObjectResponse.error:type_name -> object.ObjectErrorInfo - 1, // 8: object.WriteObjectResponse.GRN:type_name -> object.GRN - 5, // 9: object.WriteObjectResponse.object:type_name -> object.ObjectVersionInfo - 0, // 10: object.WriteObjectResponse.status:type_name -> object.WriteObjectResponse.Status - 1, // 11: object.DeleteObjectRequest.GRN:type_name -> object.GRN - 1, // 12: object.ObjectHistoryRequest.GRN:type_name -> object.GRN - 1, // 13: object.ObjectHistoryResponse.GRN:type_name -> object.GRN - 5, // 14: object.ObjectHistoryResponse.versions:type_name -> object.ObjectVersionInfo - 19, // 15: object.ObjectSearchRequest.labels:type_name -> object.ObjectSearchRequest.LabelsEntry - 1, // 16: object.ObjectSearchResult.GRN:type_name -> object.GRN - 20, // 17: object.ObjectSearchResult.labels:type_name -> object.ObjectSearchResult.LabelsEntry - 17, // 18: object.ObjectSearchResponse.results:type_name -> object.ObjectSearchResult - 6, // 19: object.ObjectStore.Read:input_type -> object.ReadObjectRequest - 8, // 20: object.ObjectStore.BatchRead:input_type -> object.BatchReadObjectRequest - 10, // 21: object.ObjectStore.Write:input_type -> object.WriteObjectRequest - 12, // 22: object.ObjectStore.Delete:input_type -> object.DeleteObjectRequest - 14, // 23: object.ObjectStore.History:input_type -> object.ObjectHistoryRequest - 16, // 24: object.ObjectStore.Search:input_type -> object.ObjectSearchRequest - 7, // 25: object.ObjectStore.Read:output_type -> object.ReadObjectResponse - 9, // 26: object.ObjectStore.BatchRead:output_type -> object.BatchReadObjectResponse - 11, // 27: object.ObjectStore.Write:output_type -> object.WriteObjectResponse - 13, // 28: object.ObjectStore.Delete:output_type -> object.DeleteObjectResponse - 15, // 29: object.ObjectStore.History:output_type -> object.ObjectHistoryResponse - 18, // 30: object.ObjectStore.Search:output_type -> object.ObjectSearchResponse - 25, // [25:31] is the sub-list for method output_type - 19, // [19:25] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 1, // 7: object.AdminWriteObjectRequest.GRN:type_name -> object.GRN + 4, // 8: object.WriteObjectResponse.error:type_name -> object.ObjectErrorInfo + 1, // 9: object.WriteObjectResponse.GRN:type_name -> object.GRN + 5, // 10: object.WriteObjectResponse.object:type_name -> object.ObjectVersionInfo + 0, // 11: object.WriteObjectResponse.status:type_name -> object.WriteObjectResponse.Status + 1, // 12: object.DeleteObjectRequest.GRN:type_name -> object.GRN + 1, // 13: object.ObjectHistoryRequest.GRN:type_name -> object.GRN + 1, // 14: object.ObjectHistoryResponse.GRN:type_name -> object.GRN + 5, // 15: object.ObjectHistoryResponse.versions:type_name -> object.ObjectVersionInfo + 20, // 16: object.ObjectSearchRequest.labels:type_name -> object.ObjectSearchRequest.LabelsEntry + 1, // 17: object.ObjectSearchResult.GRN:type_name -> object.GRN + 21, // 18: object.ObjectSearchResult.labels:type_name -> object.ObjectSearchResult.LabelsEntry + 18, // 19: object.ObjectSearchResponse.results:type_name -> object.ObjectSearchResult + 6, // 20: object.ObjectStore.Read:input_type -> object.ReadObjectRequest + 8, // 21: object.ObjectStore.BatchRead:input_type -> object.BatchReadObjectRequest + 10, // 22: object.ObjectStore.Write:input_type -> object.WriteObjectRequest + 13, // 23: object.ObjectStore.Delete:input_type -> object.DeleteObjectRequest + 15, // 24: object.ObjectStore.History:input_type -> object.ObjectHistoryRequest + 17, // 25: object.ObjectStore.Search:input_type -> object.ObjectSearchRequest + 11, // 26: object.ObjectStore.AdminWrite:input_type -> object.AdminWriteObjectRequest + 11, // 27: object.ObjectStoreAdmin.AdminWrite:input_type -> object.AdminWriteObjectRequest + 7, // 28: object.ObjectStore.Read:output_type -> object.ReadObjectResponse + 9, // 29: object.ObjectStore.BatchRead:output_type -> object.BatchReadObjectResponse + 12, // 30: object.ObjectStore.Write:output_type -> object.WriteObjectResponse + 14, // 31: object.ObjectStore.Delete:output_type -> object.DeleteObjectResponse + 16, // 32: object.ObjectStore.History:output_type -> object.ObjectHistoryResponse + 19, // 33: object.ObjectStore.Search:output_type -> object.ObjectSearchResponse + 12, // 34: object.ObjectStore.AdminWrite:output_type -> object.WriteObjectResponse + 12, // 35: object.ObjectStoreAdmin.AdminWrite:output_type -> object.WriteObjectResponse + 28, // [28:36] is the sub-list for method output_type + 20, // [20:28] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_object_proto_init() } @@ -1775,7 +1963,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RawObjectSyncInfo); i { + switch v := v.(*ObjectOriginInfo); i { case 0: return &v.state case 1: @@ -1871,7 +2059,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WriteObjectResponse); i { + switch v := v.(*AdminWriteObjectRequest); i { case 0: return &v.state case 1: @@ -1883,7 +2071,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteObjectRequest); i { + switch v := v.(*WriteObjectResponse); i { case 0: return &v.state case 1: @@ -1895,7 +2083,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteObjectResponse); i { + switch v := v.(*DeleteObjectRequest); i { case 0: return &v.state case 1: @@ -1907,7 +2095,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ObjectHistoryRequest); i { + switch v := v.(*DeleteObjectResponse); i { case 0: return &v.state case 1: @@ -1919,7 +2107,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ObjectHistoryResponse); i { + switch v := v.(*ObjectHistoryRequest); i { case 0: return &v.state case 1: @@ -1931,7 +2119,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ObjectSearchRequest); i { + switch v := v.(*ObjectHistoryResponse); i { case 0: return &v.state case 1: @@ -1943,7 +2131,7 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ObjectSearchResult); i { + switch v := v.(*ObjectSearchRequest); i { case 0: return &v.state case 1: @@ -1955,6 +2143,18 @@ func file_object_proto_init() { } } file_object_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ObjectSearchResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_object_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ObjectSearchResponse); i { case 0: return &v.state @@ -1973,9 +2173,9 @@ func file_object_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_object_proto_rawDesc, NumEnums: 1, - NumMessages: 20, + NumMessages: 21, NumExtensions: 0, - NumServices: 1, + NumServices: 2, }, GoTypes: file_object_proto_goTypes, DependencyIndexes: file_object_proto_depIdxs, diff --git a/pkg/services/store/object/object.proto b/pkg/services/store/object/object.proto index 9e69e008bbd..152681bafec 100644 --- a/pkg/services/store/object/object.proto +++ b/pkg/services/store/object/object.proto @@ -53,10 +53,10 @@ message RawObject { string version = 9; // External location info - RawObjectSyncInfo sync = 10; + ObjectOriginInfo origin = 10; } -message RawObjectSyncInfo { +message ObjectOriginInfo { // NOTE: currently managed by the dashboard_provisioning table string source = 1; @@ -156,6 +156,51 @@ message WriteObjectRequest { string previous_version = 4; } +// This operation is useful when syncing a resource from external sources +// that have more accurate metadata information (git, or an archive). +// This process can bypass the forced checks that +message AdminWriteObjectRequest { + // Object identifier + GRN GRN = 1; + + // The raw object body + bytes body = 2; + + // Message that can be seen when exploring object history + string comment = 3; + + // Time in epoch milliseconds that the object was created + // Optional, if 0 it will use the current time + int64 created_at = 4; + + // Time in epoch milliseconds that the object was updated + // Optional, if empty it will use the current user + int64 updated_at = 5; + + // Who created the object + // Optional, if 0 it will use the current time + string created_by = 6; + + // Who updated the object + // Optional, if empty it will use the current user + string updated_by = 7; + + // An explicit version identifier + // Optional, if set, this will overwrite/define an explicit version + string version = 8; + + // Used for optimistic locking. If missing, the previous version will be replaced regardless + // This may not be used along with an explicit version in the request + string previous_version = 9; + + // Request that all previous versions are removed from the history + // This will make sense for systems that manage history explicitly externallay + bool clear_history = 10; + + // Optionally define where the object came from + string origin = 11; +} + message WriteObjectResponse { // Error info -- if exists, the save did not happen ObjectErrorInfo error = 1; @@ -312,8 +357,7 @@ message ObjectSearchResponse { // Storage interface //----------------------------------------------- -// This assumes a future grpc interface where the user info is passed in context, not in each message body -// for now it will only work with an admin API key +// The object store provides a basic CRUD (+watch eventually) interface for generic objects service ObjectStore { rpc Read(ReadObjectRequest) returns (ReadObjectResponse); rpc BatchRead(BatchReadObjectRequest) returns (BatchReadObjectResponse); @@ -325,4 +369,13 @@ service ObjectStore { // Ideally an additional search endpoint with more flexibility to limit what you actually care about // https://github.com/grafana/grafana-plugin-sdk-go/blob/main/proto/backend.proto#L129 // rpc SearchEX(ObjectSearchRequest) returns (DataResponse); + + // TEMPORARY... while we split this into a new service (see below) + rpc AdminWrite(AdminWriteObjectRequest) returns (WriteObjectResponse); +} + +// The admin service extends the basic object store interface, but provides +// more explicit control that can support bulk operations like efficient git sync +service ObjectStoreAdmin { + rpc AdminWrite(AdminWriteObjectRequest) returns (WriteObjectResponse); } diff --git a/pkg/services/store/object/object_grpc.pb.go b/pkg/services/store/object/object_grpc.pb.go index 90f5d51498b..ec546c6786b 100644 --- a/pkg/services/store/object/object_grpc.pb.go +++ b/pkg/services/store/object/object_grpc.pb.go @@ -28,6 +28,8 @@ type ObjectStoreClient interface { Delete(ctx context.Context, in *DeleteObjectRequest, opts ...grpc.CallOption) (*DeleteObjectResponse, error) History(ctx context.Context, in *ObjectHistoryRequest, opts ...grpc.CallOption) (*ObjectHistoryResponse, error) Search(ctx context.Context, in *ObjectSearchRequest, opts ...grpc.CallOption) (*ObjectSearchResponse, error) + // TEMPORARY... while we split this into a new service (see below) + AdminWrite(ctx context.Context, in *AdminWriteObjectRequest, opts ...grpc.CallOption) (*WriteObjectResponse, error) } type objectStoreClient struct { @@ -92,6 +94,15 @@ func (c *objectStoreClient) Search(ctx context.Context, in *ObjectSearchRequest, return out, nil } +func (c *objectStoreClient) AdminWrite(ctx context.Context, in *AdminWriteObjectRequest, opts ...grpc.CallOption) (*WriteObjectResponse, error) { + out := new(WriteObjectResponse) + err := c.cc.Invoke(ctx, "/object.ObjectStore/AdminWrite", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ObjectStoreServer is the server API for ObjectStore service. // All implementations should embed UnimplementedObjectStoreServer // for forward compatibility @@ -102,6 +113,8 @@ type ObjectStoreServer interface { Delete(context.Context, *DeleteObjectRequest) (*DeleteObjectResponse, error) History(context.Context, *ObjectHistoryRequest) (*ObjectHistoryResponse, error) Search(context.Context, *ObjectSearchRequest) (*ObjectSearchResponse, error) + // TEMPORARY... while we split this into a new service (see below) + AdminWrite(context.Context, *AdminWriteObjectRequest) (*WriteObjectResponse, error) } // UnimplementedObjectStoreServer should be embedded to have forward compatible implementations. @@ -126,6 +139,9 @@ func (UnimplementedObjectStoreServer) History(context.Context, *ObjectHistoryReq func (UnimplementedObjectStoreServer) Search(context.Context, *ObjectSearchRequest) (*ObjectSearchResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Search not implemented") } +func (UnimplementedObjectStoreServer) AdminWrite(context.Context, *AdminWriteObjectRequest) (*WriteObjectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AdminWrite not implemented") +} // UnsafeObjectStoreServer may be embedded to opt out of forward compatibility for this service. // Use of this interface is not recommended, as added methods to ObjectStoreServer will @@ -246,6 +262,24 @@ func _ObjectStore_Search_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _ObjectStore_AdminWrite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdminWriteObjectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ObjectStoreServer).AdminWrite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/object.ObjectStore/AdminWrite", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ObjectStoreServer).AdminWrite(ctx, req.(*AdminWriteObjectRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ObjectStore_ServiceDesc is the grpc.ServiceDesc for ObjectStore service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -277,6 +311,94 @@ var ObjectStore_ServiceDesc = grpc.ServiceDesc{ MethodName: "Search", Handler: _ObjectStore_Search_Handler, }, + { + MethodName: "AdminWrite", + Handler: _ObjectStore_AdminWrite_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "object.proto", +} + +// ObjectStoreAdminClient is the client API for ObjectStoreAdmin service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ObjectStoreAdminClient interface { + AdminWrite(ctx context.Context, in *AdminWriteObjectRequest, opts ...grpc.CallOption) (*WriteObjectResponse, error) +} + +type objectStoreAdminClient struct { + cc grpc.ClientConnInterface +} + +func NewObjectStoreAdminClient(cc grpc.ClientConnInterface) ObjectStoreAdminClient { + return &objectStoreAdminClient{cc} +} + +func (c *objectStoreAdminClient) AdminWrite(ctx context.Context, in *AdminWriteObjectRequest, opts ...grpc.CallOption) (*WriteObjectResponse, error) { + out := new(WriteObjectResponse) + err := c.cc.Invoke(ctx, "/object.ObjectStoreAdmin/AdminWrite", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ObjectStoreAdminServer is the server API for ObjectStoreAdmin service. +// All implementations should embed UnimplementedObjectStoreAdminServer +// for forward compatibility +type ObjectStoreAdminServer interface { + AdminWrite(context.Context, *AdminWriteObjectRequest) (*WriteObjectResponse, error) +} + +// UnimplementedObjectStoreAdminServer should be embedded to have forward compatible implementations. +type UnimplementedObjectStoreAdminServer struct { +} + +func (UnimplementedObjectStoreAdminServer) AdminWrite(context.Context, *AdminWriteObjectRequest) (*WriteObjectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AdminWrite not implemented") +} + +// UnsafeObjectStoreAdminServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ObjectStoreAdminServer will +// result in compilation errors. +type UnsafeObjectStoreAdminServer interface { + mustEmbedUnimplementedObjectStoreAdminServer() +} + +func RegisterObjectStoreAdminServer(s grpc.ServiceRegistrar, srv ObjectStoreAdminServer) { + s.RegisterService(&ObjectStoreAdmin_ServiceDesc, srv) +} + +func _ObjectStoreAdmin_AdminWrite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdminWriteObjectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ObjectStoreAdminServer).AdminWrite(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/object.ObjectStoreAdmin/AdminWrite", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ObjectStoreAdminServer).AdminWrite(ctx, req.(*AdminWriteObjectRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ObjectStoreAdmin_ServiceDesc is the grpc.ServiceDesc for ObjectStoreAdmin service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ObjectStoreAdmin_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "object.ObjectStoreAdmin", + HandlerType: (*ObjectStoreAdminServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AdminWrite", + Handler: _ObjectStoreAdmin_AdminWrite_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "object.proto", diff --git a/pkg/services/store/object/sqlstash/sql_storage_server.go b/pkg/services/store/object/sqlstash/sql_storage_server.go index 04a78396ef7..29e23cec334 100644 --- a/pkg/services/store/object/sqlstash/sql_storage_server.go +++ b/pkg/services/store/object/sqlstash/sql_storage_server.go @@ -23,6 +23,10 @@ import ( "github.com/grafana/grafana/pkg/setting" ) +// Make sure we implement both store + admin +var _ object.ObjectStoreServer = &sqlObjectServer{} +var _ object.ObjectStoreAdminServer = &sqlObjectServer{} + func ProvideSQLObjectServer(db db.DB, cfg *setting.Cfg, grpcServerProvider grpcserver.Provider, kinds kind.KindRegistry, resolver resolver.ObjectReferenceResolver) object.ObjectStoreServer { objectServer := &sqlObjectServer{ sess: db.GetSqlxSession(), @@ -49,7 +53,7 @@ func getReadSelect(r *object.ReadObjectRequest) string { "size", "etag", "errors", // errors are always returned "created_at", "created_by", "updated_at", "updated_by", - "sync_src", "sync_time"} + "origin", "origin_ts"} if r.WithBody { fields = append(fields, `body`) @@ -62,8 +66,8 @@ func getReadSelect(r *object.ReadObjectRequest) string { func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql.Rows, r *object.ReadObjectRequest) (*object.ReadObjectResponse, error) { path := "" // string (extract UID?) - var syncSrc sql.NullString - var syncTime sql.NullTime + var origin sql.NullString + originTime := int64(0) raw := &object.RawObject{ GRN: &object.GRN{}, } @@ -74,7 +78,7 @@ func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql &raw.Size, &raw.ETag, &summaryjson.errors, &raw.CreatedAt, &raw.CreatedBy, &raw.UpdatedAt, &raw.UpdatedBy, - &syncSrc, &syncTime, + &origin, &originTime, } if r.WithBody { args = append(args, &raw.Body) @@ -88,10 +92,10 @@ func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql return nil, err } - if syncSrc.Valid || syncTime.Valid { - raw.Sync = &object.RawObjectSyncInfo{ - Source: syncSrc.String, - Time: syncTime.Time.UnixMilli(), + if origin.Valid { + raw.Origin = &object.ObjectOriginInfo{ + Source: origin.String, + Time: originTime, } } @@ -273,6 +277,11 @@ func (s *sqlObjectServer) BatchRead(ctx context.Context, b *object.BatchReadObje } func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectRequest) (*object.WriteObjectResponse, error) { + return s.AdminWrite(ctx, object.ToAdminWriteObjectRequest(r)) +} + +//nolint:gocyclo +func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteObjectRequest) (*object.WriteObjectResponse, error) { route, err := s.getObjectKey(ctx, r.GRN) if err != nil { return nil, err @@ -282,9 +291,20 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques return nil, fmt.Errorf("invalid grn") } - modifier := store.UserFromContext(ctx) - if modifier == nil { - return nil, fmt.Errorf("can not find user in context") + timestamp := time.Now().UnixMilli() + createdAt := r.CreatedAt + createdBy := r.CreatedBy + updatedAt := r.UpdatedAt + updatedBy := r.UpdatedBy + if updatedBy == "" { + modifier := store.UserFromContext(ctx) + if modifier == nil { + return nil, fmt.Errorf("can not find user in context") + } + updatedBy = store.GetUserIDString(modifier) + } + if updatedAt < 1000 { + updatedAt = timestamp } summary, body, err := s.prepare(ctx, r) @@ -309,10 +329,26 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques } err = s.sess.WithTransaction(ctx, func(tx *session.SessionTx) error { + var versionInfo *object.ObjectVersionInfo isUpdate := false - versionInfo, err := s.selectForUpdate(ctx, tx, path) - if err != nil { - return err + if r.ClearHistory { + // Optionally keep the original creation time information + if createdAt < 1000 || createdBy == "" { + err = s.fillCreationInfo(ctx, tx, path, &createdAt, &createdBy) + if err != nil { + return err + } + } + _, err = doDelete(ctx, tx, path) + if err != nil { + return err + } + versionInfo = &object.ObjectVersionInfo{} + } else { + versionInfo, err = s.selectForUpdate(ctx, tx, path) + if err != nil { + return err + } } // Same object @@ -330,18 +366,21 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques } // Set the comment on this write - timestamp := time.Now().UnixMilli() versionInfo.Comment = r.Comment - if versionInfo.Version == "" { - versionInfo.Version = "1" - } else { - // Increment the version - i, _ := strconv.ParseInt(versionInfo.Version, 0, 64) - if i < 1 { - i = timestamp + if r.Version == "" { + if versionInfo.Version == "" { + versionInfo.Version = "1" + } else { + // Increment the version + i, _ := strconv.ParseInt(versionInfo.Version, 0, 64) + if i < 1 { + i = timestamp + } + versionInfo.Version = fmt.Sprintf("%d", i+1) + isUpdate = true } - versionInfo.Version = fmt.Sprintf("%d", i+1) - isUpdate = true + } else { + versionInfo.Version = r.Version } if isUpdate { @@ -357,8 +396,8 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques // 1. Add the `object_history` values versionInfo.Size = int64(len(body)) versionInfo.ETag = etag - versionInfo.UpdatedAt = timestamp - versionInfo.UpdatedBy = store.GetUserIDString(modifier) + versionInfo.UpdatedAt = updatedAt + versionInfo.UpdatedBy = updatedBy _, err = tx.Exec(ctx, `INSERT INTO object_history (`+ "path, version, message, "+ "size, body, etag, "+ @@ -366,7 +405,7 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", path, versionInfo.Version, versionInfo.Comment, versionInfo.Size, body, versionInfo.ETag, - timestamp, versionInfo.UpdatedBy, + updatedAt, versionInfo.UpdatedBy, ) if err != nil { return err @@ -411,27 +450,35 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques "body=?, size=?, etag=?, version=?, "+ "updated_at=?, updated_by=?,"+ "name=?, description=?,"+ - "labels=?, fields=?, errors=? "+ + "labels=?, fields=?, errors=?, "+ + "origin=?, origin_ts=? "+ "WHERE path=?", body, versionInfo.Size, etag, versionInfo.Version, - timestamp, versionInfo.UpdatedBy, + updatedAt, versionInfo.UpdatedBy, summary.model.Name, summary.model.Description, summary.labels, summary.fields, summary.errors, + r.Origin, timestamp, path, ) return err } - // Insert the new row + if createdAt < 1000 { + createdAt = updatedAt + } + if createdBy == "" { + createdBy = updatedBy + } + _, err = tx.Exec(ctx, "INSERT INTO object ("+ - "path, parent_folder_path, kind, size, body, etag, version,"+ - "updated_at, updated_by, created_at, created_by,"+ - "name, description,"+ + "path, parent_folder_path, kind, size, body, etag, version, "+ + "updated_at, updated_by, created_at, created_by, "+ + "name, description, origin, origin_ts, "+ "labels, fields, errors) "+ - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", path, getParentFolderPath(grn.Kind, path), grn.Kind, versionInfo.Size, body, etag, versionInfo.Version, - timestamp, versionInfo.UpdatedBy, timestamp, versionInfo.UpdatedBy, // created + updated are the same - summary.model.Name, summary.model.Description, + updatedAt, createdBy, createdAt, createdBy, // created + updated are the same + summary.model.Name, summary.model.Description, r.Origin, timestamp, summary.labels, summary.fields, summary.errors, ) return err @@ -443,6 +490,28 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques return rsp, err } +func (s *sqlObjectServer) fillCreationInfo(ctx context.Context, tx *session.SessionTx, path string, createdAt *int64, createdBy *string) error { + if *createdAt > 1000 { + ignore := int64(0) + createdAt = &ignore + } + if *createdBy == "" { + ignore := "" + createdBy = &ignore + } + + rows, err := tx.Query(ctx, "SELECT created_at,created_by FROM object WHERE path=?", path) + if err == nil { + if rows.Next() { + err = rows.Scan(&createdAt, &createdBy) + } + if err == nil { + err = rows.Close() + } + } + return err +} + func (s *sqlObjectServer) selectForUpdate(ctx context.Context, tx *session.SessionTx, path string) (*object.ObjectVersionInfo, error) { q := "SELECT etag,version,updated_at,size FROM object WHERE path=?" if false { // TODO, MYSQL/PosgreSQL can lock the row " FOR UPDATE" @@ -462,7 +531,7 @@ func (s *sqlObjectServer) selectForUpdate(ctx context.Context, tx *session.Sessi return current, err } -func (s *sqlObjectServer) prepare(ctx context.Context, r *object.WriteObjectRequest) (*summarySupport, []byte, error) { +func (s *sqlObjectServer) prepare(ctx context.Context, r *object.AdminWriteObjectRequest) (*summarySupport, []byte, error) { grn := r.GRN builder := s.kinds.GetSummaryBuilder(grn.Kind) if builder == nil { @@ -490,27 +559,29 @@ func (s *sqlObjectServer) Delete(ctx context.Context, r *object.DeleteObjectRequ rsp := &object.DeleteObjectResponse{} err = s.sess.WithTransaction(ctx, func(tx *session.SessionTx) error { - results, err := tx.Exec(ctx, "DELETE FROM object WHERE path=?", path) - if err != nil { - return err - } - rows, err := results.RowsAffected() - if err != nil { - return err - } - if rows > 0 { - rsp.OK = true - } - - // TODO: keep history? would need current version bump, and the "write" would have to get from history - _, _ = tx.Exec(ctx, "DELETE FROM object_history WHERE path=?", path) - _, _ = tx.Exec(ctx, "DELETE FROM object_labels WHERE path=?", path) - _, _ = tx.Exec(ctx, "DELETE FROM object_ref WHERE path=?", path) - return nil + rsp.OK, err = doDelete(ctx, tx, path) + return err }) return rsp, err } +func doDelete(ctx context.Context, tx *session.SessionTx, path string) (bool, error) { + results, err := tx.Exec(ctx, "DELETE FROM object WHERE path=?", path) + if err != nil { + return false, err + } + rows, err := results.RowsAffected() + if err != nil { + return false, err + } + + // TODO: keep history? would need current version bump, and the "write" would have to get from history + _, _ = tx.Exec(ctx, "DELETE FROM object_history WHERE path=?", path) + _, _ = tx.Exec(ctx, "DELETE FROM object_labels WHERE path=?", path) + _, _ = tx.Exec(ctx, "DELETE FROM object_ref WHERE path=?", path) + return rows > 0, err +} + func (s *sqlObjectServer) History(ctx context.Context, r *object.ObjectHistoryRequest) (*object.ObjectHistoryResponse, error) { route, err := s.getObjectKey(ctx, r.GRN) if err != nil { diff --git a/pkg/services/store/object/utils.go b/pkg/services/store/object/utils.go new file mode 100644 index 00000000000..9aac9eb8e29 --- /dev/null +++ b/pkg/services/store/object/utils.go @@ -0,0 +1,11 @@ +package object + +// The admin request is a superset of write request features +func ToAdminWriteObjectRequest(req *WriteObjectRequest) *AdminWriteObjectRequest { + return &AdminWriteObjectRequest{ + GRN: req.GRN, + Body: req.Body, + Comment: req.Comment, + PreviousVersion: req.PreviousVersion, + } +}