From 0e73a30ddb4a6bf9d7c0e407e1cd53827db539cb Mon Sep 17 00:00:00 2001 From: Tim Burks Date: Mon, 22 Nov 2021 12:31:33 -0800 Subject: [PATCH] Add a "migrate database" API. (#393) --- cmd/apg/admin_service.go | 3 +- cmd/apg/migrate-database.go | 143 +++++ gapic/admin_client.go | 150 ++++- gapic/admin_client_example_test.go | 25 + .../apigeeregistry/v1/admin_service.proto | 29 + rpc/admin_service.pb.go | 533 ++++++++++++------ rpc/admin_service_grpc.pb.go | 39 ++ server/registry/actions_migrate_database.go | 53 ++ .../registry/internal/storage/gorm/client.go | 29 +- 9 files changed, 815 insertions(+), 189 deletions(-) create mode 100644 cmd/apg/migrate-database.go create mode 100644 server/registry/actions_migrate_database.go diff --git a/cmd/apg/admin_service.go b/cmd/apg/admin_service.go index dff2e74a7..5cc41f624 100644 --- a/cmd/apg/admin_service.go +++ b/cmd/apg/admin_service.go @@ -18,7 +18,8 @@ var AdminConfig *viper.Viper var AdminClient *gapic.AdminClient var AdminSubCommands []string = []string{ "get-status", - "list-projects", + "migrate-database", + "poll-migrate-database", "list-projects", "get-project", "create-project", "update-project", diff --git a/cmd/apg/migrate-database.go b/cmd/apg/migrate-database.go new file mode 100644 index 000000000..4013ba6f1 --- /dev/null +++ b/cmd/apg/migrate-database.go @@ -0,0 +1,143 @@ +// Code generated. DO NOT EDIT. + +package main + +import ( + "github.com/spf13/cobra" + + "fmt" + + "github.com/golang/protobuf/jsonpb" + + "os" + + rpcpb "github.com/apigee/registry/rpc" +) + +var MigrateDatabaseInput rpcpb.MigrateDatabaseRequest + +var MigrateDatabaseFromFile string + +var MigrateDatabaseFollow bool + +var MigrateDatabasePollOperation string + +func init() { + AdminServiceCmd.AddCommand(MigrateDatabaseCmd) + + MigrateDatabaseCmd.Flags().StringVar(&MigrateDatabaseInput.Kind, "kind", "", "A string describing the kind of migration to...") + + MigrateDatabaseCmd.Flags().StringVar(&MigrateDatabaseFromFile, "from_file", "", "Absolute path to JSON file containing request payload") + + MigrateDatabaseCmd.Flags().BoolVar(&MigrateDatabaseFollow, "follow", false, "Block until the long running operation completes") + + AdminServiceCmd.AddCommand(MigrateDatabasePollCmd) + + MigrateDatabasePollCmd.Flags().BoolVar(&MigrateDatabaseFollow, "follow", false, "Block until the long running operation completes") + + MigrateDatabasePollCmd.Flags().StringVar(&MigrateDatabasePollOperation, "operation", "", "Required. Operation name to poll for") + + MigrateDatabasePollCmd.MarkFlagRequired("operation") + +} + +var MigrateDatabaseCmd = &cobra.Command{ + Use: "migrate-database", + Short: "MigrateDatabase attempts to migrate the database...", + Long: "MigrateDatabase attempts to migrate the database to the current schema.", + PreRun: func(cmd *cobra.Command, args []string) { + + if MigrateDatabaseFromFile == "" { + + } + + }, + RunE: func(cmd *cobra.Command, args []string) (err error) { + + in := os.Stdin + if MigrateDatabaseFromFile != "" { + in, err = os.Open(MigrateDatabaseFromFile) + if err != nil { + return err + } + defer in.Close() + + err = jsonpb.Unmarshal(in, &MigrateDatabaseInput) + if err != nil { + return err + } + + } + + if Verbose { + printVerboseInput("Admin", "MigrateDatabase", &MigrateDatabaseInput) + } + resp, err := AdminClient.MigrateDatabase(ctx, &MigrateDatabaseInput) + if err != nil { + return err + } + + if !MigrateDatabaseFollow { + var s interface{} + s = resp.Name() + + if OutputJSON { + d := make(map[string]string) + d["operation"] = resp.Name() + s = d + } + + printMessage(s) + return err + } + + result, err := resp.Wait(ctx) + if err != nil { + return err + } + + if Verbose { + fmt.Print("Output: ") + } + printMessage(result) + + return err + }, +} + +var MigrateDatabasePollCmd = &cobra.Command{ + Use: "poll-migrate-database", + Short: "Poll the status of a MigrateDatabaseOperation by name", + RunE: func(cmd *cobra.Command, args []string) (err error) { + op := AdminClient.MigrateDatabaseOperation(MigrateDatabasePollOperation) + + if MigrateDatabaseFollow { + resp, err := op.Wait(ctx) + if err != nil { + return err + } + + if Verbose { + fmt.Print("Output: ") + } + printMessage(resp) + return err + } + + resp, err := op.Poll(ctx) + if err != nil { + return err + } else if resp != nil { + if Verbose { + fmt.Print("Output: ") + } + + printMessage(resp) + return + } + + fmt.Println(fmt.Sprintf("Operation %s not done", op.Name())) + + return err + }, +} diff --git a/gapic/admin_client.go b/gapic/admin_client.go index ff6cae8d1..7132ab001 100644 --- a/gapic/admin_client.go +++ b/gapic/admin_client.go @@ -21,13 +21,17 @@ import ( "fmt" "math" "net/url" + "time" + "cloud.google.com/go/longrunning" + lroauto "cloud.google.com/go/longrunning/autogen" rpcpb "github.com/apigee/registry/rpc" gax "github.com/googleapis/gax-go/v2" "google.golang.org/api/iterator" "google.golang.org/api/option" "google.golang.org/api/option/internaloption" gtransport "google.golang.org/api/transport/grpc" + longrunningpb "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" @@ -38,12 +42,13 @@ var newAdminClientHook clientHook // AdminCallOptions contains the retry settings for each method of AdminClient. type AdminCallOptions struct { - GetStatus []gax.CallOption - ListProjects []gax.CallOption - GetProject []gax.CallOption - CreateProject []gax.CallOption - UpdateProject []gax.CallOption - DeleteProject []gax.CallOption + GetStatus []gax.CallOption + MigrateDatabase []gax.CallOption + ListProjects []gax.CallOption + GetProject []gax.CallOption + CreateProject []gax.CallOption + UpdateProject []gax.CallOption + DeleteProject []gax.CallOption } func defaultAdminGRPCClientOptions() []option.ClientOption { @@ -60,12 +65,13 @@ func defaultAdminGRPCClientOptions() []option.ClientOption { func defaultAdminCallOptions() *AdminCallOptions { return &AdminCallOptions{ - GetStatus: []gax.CallOption{}, - ListProjects: []gax.CallOption{}, - GetProject: []gax.CallOption{}, - CreateProject: []gax.CallOption{}, - UpdateProject: []gax.CallOption{}, - DeleteProject: []gax.CallOption{}, + GetStatus: []gax.CallOption{}, + MigrateDatabase: []gax.CallOption{}, + ListProjects: []gax.CallOption{}, + GetProject: []gax.CallOption{}, + CreateProject: []gax.CallOption{}, + UpdateProject: []gax.CallOption{}, + DeleteProject: []gax.CallOption{}, } } @@ -75,6 +81,8 @@ type internalAdminClient interface { setGoogleClientInfo(...string) Connection() *grpc.ClientConn GetStatus(context.Context, *emptypb.Empty, ...gax.CallOption) (*rpcpb.Status, error) + MigrateDatabase(context.Context, *rpcpb.MigrateDatabaseRequest, ...gax.CallOption) (*MigrateDatabaseOperation, error) + MigrateDatabaseOperation(name string) *MigrateDatabaseOperation ListProjects(context.Context, *rpcpb.ListProjectsRequest, ...gax.CallOption) *ProjectIterator GetProject(context.Context, *rpcpb.GetProjectRequest, ...gax.CallOption) (*rpcpb.Project, error) CreateProject(context.Context, *rpcpb.CreateProjectRequest, ...gax.CallOption) (*rpcpb.Project, error) @@ -93,6 +101,11 @@ type AdminClient struct { // The call options for this service. CallOptions *AdminCallOptions + + // LROClient is used internally to handle long-running operations. + // It is exposed so that its CallOptions can be modified if required. + // Users should not Close this client. + LROClient *lroauto.OperationsClient } // Wrapper methods routed to the internal client. @@ -128,6 +141,17 @@ func (c *AdminClient) GetStatus(ctx context.Context, req *emptypb.Empty, opts .. return c.internalClient.GetStatus(ctx, req, opts...) } +// MigrateDatabase migrateDatabase attempts to migrate the database to the current schema. +func (c *AdminClient) MigrateDatabase(ctx context.Context, req *rpcpb.MigrateDatabaseRequest, opts ...gax.CallOption) (*MigrateDatabaseOperation, error) { + return c.internalClient.MigrateDatabase(ctx, req, opts...) +} + +// MigrateDatabaseOperation returns a new MigrateDatabaseOperation from a given name. +// The name must be that of a previously created MigrateDatabaseOperation, possibly from a different process. +func (c *AdminClient) MigrateDatabaseOperation(name string) *MigrateDatabaseOperation { + return c.internalClient.MigrateDatabaseOperation(name) +} + // ListProjects listProjects returns matching projects. // (– api-linter: standard-methods=disabled –) // (– api-linter: core::0132::method-signature=disabled @@ -178,6 +202,11 @@ type adminGRPCClient struct { // The gRPC API client. adminClient rpcpb.AdminClient + // LROClient is used internally to handle long-running operations. + // It is exposed so that its CallOptions can be modified if required. + // Users should not Close this client. + LROClient **lroauto.OperationsClient + // The x-goog-* metadata to be sent with each request. xGoogMetadata metadata.MD } @@ -218,6 +247,17 @@ func NewAdminClient(ctx context.Context, opts ...option.ClientOption) (*AdminCli client.internalClient = c + client.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool)) + if err != nil { + // This error "should not happen", since we are just reusing old connection pool + // and never actually need to dial. + // If this does happen, we could leak connp. However, we cannot close conn: + // If the user invoked the constructor with option.WithGRPCConn, + // we would close a connection that's still in use. + // TODO: investigate error conditions. + return nil, err + } + c.LROClient = &client.LROClient return &client, nil } @@ -258,6 +298,23 @@ func (c *adminGRPCClient) GetStatus(ctx context.Context, req *emptypb.Empty, opt return resp, nil } +func (c *adminGRPCClient) MigrateDatabase(ctx context.Context, req *rpcpb.MigrateDatabaseRequest, opts ...gax.CallOption) (*MigrateDatabaseOperation, error) { + ctx = insertMetadata(ctx, c.xGoogMetadata) + opts = append((*c.CallOptions).MigrateDatabase[0:len((*c.CallOptions).MigrateDatabase):len((*c.CallOptions).MigrateDatabase)], opts...) + var resp *longrunningpb.Operation + err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error { + var err error + resp, err = c.adminClient.MigrateDatabase(ctx, req, settings.GRPC...) + return err + }, opts...) + if err != nil { + return nil, err + } + return &MigrateDatabaseOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, resp), + }, nil +} + func (c *adminGRPCClient) ListProjects(ctx context.Context, req *rpcpb.ListProjectsRequest, opts ...gax.CallOption) *ProjectIterator { ctx = insertMetadata(ctx, c.xGoogMetadata) opts = append((*c.CallOptions).ListProjects[0:len((*c.CallOptions).ListProjects):len((*c.CallOptions).ListProjects)], opts...) @@ -360,6 +417,75 @@ func (c *adminGRPCClient) DeleteProject(ctx context.Context, req *rpcpb.DeletePr return err } +// MigrateDatabaseOperation manages a long-running operation from MigrateDatabase. +type MigrateDatabaseOperation struct { + lro *longrunning.Operation +} + +// MigrateDatabaseOperation returns a new MigrateDatabaseOperation from a given name. +// The name must be that of a previously created MigrateDatabaseOperation, possibly from a different process. +func (c *adminGRPCClient) MigrateDatabaseOperation(name string) *MigrateDatabaseOperation { + return &MigrateDatabaseOperation{ + lro: longrunning.InternalNewOperation(*c.LROClient, &longrunningpb.Operation{Name: name}), + } +} + +// Wait blocks until the long-running operation is completed, returning the response and any errors encountered. +// +// See documentation of Poll for error-handling information. +func (op *MigrateDatabaseOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*rpcpb.MigrateDatabaseResponse, error) { + var resp rpcpb.MigrateDatabaseResponse + if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil { + return nil, err + } + return &resp, nil +} + +// Poll fetches the latest state of the long-running operation. +// +// Poll also fetches the latest metadata, which can be retrieved by Metadata. +// +// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and +// the operation has completed with failure, the error is returned and op.Done will return true. +// If Poll succeeds and the operation has completed successfully, +// op.Done will return true, and the response of the operation is returned. +// If Poll succeeds and the operation has not completed, the returned response and error are both nil. +func (op *MigrateDatabaseOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*rpcpb.MigrateDatabaseResponse, error) { + var resp rpcpb.MigrateDatabaseResponse + if err := op.lro.Poll(ctx, &resp, opts...); err != nil { + return nil, err + } + if !op.Done() { + return nil, nil + } + return &resp, nil +} + +// Metadata returns metadata associated with the long-running operation. +// Metadata itself does not contact the server, but Poll does. +// To get the latest metadata, call this method after a successful call to Poll. +// If the metadata is not available, the returned metadata and error are both nil. +func (op *MigrateDatabaseOperation) Metadata() (*rpcpb.MigrateDatabaseMetadata, error) { + var meta rpcpb.MigrateDatabaseMetadata + if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata { + return nil, nil + } else if err != nil { + return nil, err + } + return &meta, nil +} + +// Done reports whether the long-running operation has completed. +func (op *MigrateDatabaseOperation) Done() bool { + return op.lro.Done() +} + +// Name returns the name of the long-running operation. +// The name is assigned by the server and is unique within the service from which the operation is created. +func (op *MigrateDatabaseOperation) Name() string { + return op.lro.Name() +} + // ProjectIterator manages a stream of *rpcpb.Project. type ProjectIterator struct { items []*rpcpb.Project diff --git a/gapic/admin_client_example_test.go b/gapic/admin_client_example_test.go index a284b96e7..ad806a5c9 100644 --- a/gapic/admin_client_example_test.go +++ b/gapic/admin_client_example_test.go @@ -57,6 +57,31 @@ func ExampleAdminClient_GetStatus() { _ = resp } +func ExampleAdminClient_MigrateDatabase() { + ctx := context.Background() + c, err := gapic.NewAdminClient(ctx) + if err != nil { + // TODO: Handle error. + } + defer c.Close() + + req := &rpcpb.MigrateDatabaseRequest{ + // TODO: Fill request struct fields. + // See https://pkg.go.dev/github.com/apigee/registry/rpc#MigrateDatabaseRequest. + } + op, err := c.MigrateDatabase(ctx, req) + if err != nil { + // TODO: Handle error. + } + + resp, err := op.Wait(ctx) + if err != nil { + // TODO: Handle error. + } + // TODO: Use resp. + _ = resp +} + func ExampleAdminClient_ListProjects() { ctx := context.Background() c, err := gapic.NewAdminClient(ctx) diff --git a/google/cloud/apigeeregistry/v1/admin_service.proto b/google/cloud/apigeeregistry/v1/admin_service.proto index 1fb3a57d0..366677259 100644 --- a/google/cloud/apigeeregistry/v1/admin_service.proto +++ b/google/cloud/apigeeregistry/v1/admin_service.proto @@ -21,6 +21,7 @@ import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/api/resource.proto"; import "google/cloud/apigeeregistry/v1/admin_models.proto"; +import "google/longrunning/operations.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/field_mask.proto"; @@ -47,6 +48,17 @@ service Admin { }; } + // MigrateDatabase attempts to migrate the database to the current schema. + rpc MigrateDatabase(MigrateDatabaseRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/migrateDatabase" + }; + option (google.longrunning.operation_info) = { + response_type : "MigrateDatabaseResponse", + metadata_type : "MigrateDatabaseMetadata" + }; + } + // ListProjects returns matching projects. // (-- api-linter: standard-methods=disabled --) // (-- api-linter: core::0132::method-signature=disabled @@ -105,6 +117,23 @@ message Status { string message = 1; } +// Request message for MigrateDatabase. +message MigrateDatabaseRequest { + // A string describing the kind of migration to perform. + // Currently only "auto" is recognized (and is the default if omitted). + string kind = 1; +} + +// Metadata message for MigrateDatabase. +message MigrateDatabaseMetadata { +} + +// Response message for MigrateDatabase. +message MigrateDatabaseResponse { + // A string describing the result of the migration. + string message = 1; +} + // Request message for ListProjects. // (-- api-linter: core::0132::request-parent-required=disabled // aip.dev/not-precedent: the parent of Project is implicit. --) diff --git a/rpc/admin_service.pb.go b/rpc/admin_service.pb.go index bb71a5131..38d50a527 100644 --- a/rpc/admin_service.pb.go +++ b/rpc/admin_service.pb.go @@ -25,6 +25,7 @@ import ( sync "sync" _ "google.golang.org/genproto/googleapis/api/annotations" + longrunning "google.golang.org/genproto/googleapis/longrunning" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -88,6 +89,144 @@ func (x *Status) GetMessage() string { return "" } +// Request message for MigrateDatabase. +type MigrateDatabaseRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A string describing the kind of migration to perform. + // Currently only "auto" is recognized (and is the default if omitted). + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` +} + +func (x *MigrateDatabaseRequest) Reset() { + *x = MigrateDatabaseRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MigrateDatabaseRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrateDatabaseRequest) ProtoMessage() {} + +func (x *MigrateDatabaseRequest) ProtoReflect() protoreflect.Message { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[1] + 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 MigrateDatabaseRequest.ProtoReflect.Descriptor instead. +func (*MigrateDatabaseRequest) Descriptor() ([]byte, []int) { + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{1} +} + +func (x *MigrateDatabaseRequest) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +// Metadata message for MigrateDatabase. +type MigrateDatabaseMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MigrateDatabaseMetadata) Reset() { + *x = MigrateDatabaseMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MigrateDatabaseMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrateDatabaseMetadata) ProtoMessage() {} + +func (x *MigrateDatabaseMetadata) ProtoReflect() protoreflect.Message { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[2] + 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 MigrateDatabaseMetadata.ProtoReflect.Descriptor instead. +func (*MigrateDatabaseMetadata) Descriptor() ([]byte, []int) { + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{2} +} + +// Response message for MigrateDatabase. +type MigrateDatabaseResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A string describing the result of the migration. + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *MigrateDatabaseResponse) Reset() { + *x = MigrateDatabaseResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MigrateDatabaseResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrateDatabaseResponse) ProtoMessage() {} + +func (x *MigrateDatabaseResponse) ProtoReflect() protoreflect.Message { + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[3] + 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 MigrateDatabaseResponse.ProtoReflect.Descriptor instead. +func (*MigrateDatabaseResponse) Descriptor() ([]byte, []int) { + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{3} +} + +func (x *MigrateDatabaseResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + // Request message for ListProjects. // (-- api-linter: core::0132::request-parent-required=disabled // aip.dev/not-precedent: the parent of Project is implicit. --) @@ -115,7 +254,7 @@ type ListProjectsRequest struct { func (x *ListProjectsRequest) Reset() { *x = ListProjectsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[1] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -128,7 +267,7 @@ func (x *ListProjectsRequest) String() string { func (*ListProjectsRequest) ProtoMessage() {} func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[1] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -141,7 +280,7 @@ func (x *ListProjectsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProjectsRequest.ProtoReflect.Descriptor instead. func (*ListProjectsRequest) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{1} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{4} } func (x *ListProjectsRequest) GetPageSize() int32 { @@ -181,7 +320,7 @@ type ListProjectsResponse struct { func (x *ListProjectsResponse) Reset() { *x = ListProjectsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[2] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -194,7 +333,7 @@ func (x *ListProjectsResponse) String() string { func (*ListProjectsResponse) ProtoMessage() {} func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[2] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -207,7 +346,7 @@ func (x *ListProjectsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProjectsResponse.ProtoReflect.Descriptor instead. func (*ListProjectsResponse) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{2} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{5} } func (x *ListProjectsResponse) GetProjects() []*Project { @@ -238,7 +377,7 @@ type GetProjectRequest struct { func (x *GetProjectRequest) Reset() { *x = GetProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[3] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -251,7 +390,7 @@ func (x *GetProjectRequest) String() string { func (*GetProjectRequest) ProtoMessage() {} func (x *GetProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[3] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -264,7 +403,7 @@ func (x *GetProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProjectRequest.ProtoReflect.Descriptor instead. func (*GetProjectRequest) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{3} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{6} } func (x *GetProjectRequest) GetName() string { @@ -295,7 +434,7 @@ type CreateProjectRequest struct { func (x *CreateProjectRequest) Reset() { *x = CreateProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[4] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -308,7 +447,7 @@ func (x *CreateProjectRequest) String() string { func (*CreateProjectRequest) ProtoMessage() {} func (x *CreateProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[4] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -321,7 +460,7 @@ func (x *CreateProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateProjectRequest.ProtoReflect.Descriptor instead. func (*CreateProjectRequest) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{4} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{7} } func (x *CreateProjectRequest) GetProject() *Project { @@ -362,7 +501,7 @@ type UpdateProjectRequest struct { func (x *UpdateProjectRequest) Reset() { *x = UpdateProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[5] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -375,7 +514,7 @@ func (x *UpdateProjectRequest) String() string { func (*UpdateProjectRequest) ProtoMessage() {} func (x *UpdateProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[5] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -388,7 +527,7 @@ func (x *UpdateProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProjectRequest.ProtoReflect.Descriptor instead. func (*UpdateProjectRequest) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{5} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{8} } func (x *UpdateProjectRequest) GetProject() *Project { @@ -426,7 +565,7 @@ type DeleteProjectRequest struct { func (x *DeleteProjectRequest) Reset() { *x = DeleteProjectRequest{} if protoimpl.UnsafeEnabled { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[6] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -439,7 +578,7 @@ func (x *DeleteProjectRequest) String() string { func (*DeleteProjectRequest) ProtoMessage() {} func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message { - mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[6] + mi := &file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -452,7 +591,7 @@ func (x *DeleteProjectRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProjectRequest.ProtoReflect.Descriptor instead. func (*DeleteProjectRequest) Descriptor() ([]byte, []int) { - return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{6} + return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP(), []int{9} } func (x *DeleteProjectRequest) GetName() string { @@ -480,123 +619,145 @@ var file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDesc = []byte{ 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, - 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x06, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x69, 0x0a, - 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x43, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x08, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 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, 0x22, 0x56, - 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x64, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x23, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x2f, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, + 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x33, 0x0a, 0x17, 0x4d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x69, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, + 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x83, 0x01, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 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, 0x22, 0x56, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x2d, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x27, 0x0a, 0x25, 0x61, 0x70, + 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x46, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x46, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, + 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x22, 0x59, 0x0a, 0x14, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2d, 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x27, 0x0a, 0x25, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7d, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, - 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, - 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x49, 0x64, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, - 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, - 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, - 0x61, 0x73, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x22, 0x59, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x41, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2d, - 0xe0, 0x41, 0x02, 0xfa, 0x41, 0x27, 0x0a, 0x25, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, - 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x32, 0x8f, 0x07, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x5f, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, - 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x8f, - 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, - 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, - 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, - 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, - 0x12, 0x8e, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, - 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, - 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, - 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x24, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0xa2, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, - 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x3a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0xda, 0x41, 0x12, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x12, 0xb4, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, - 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x32, - 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6e, 0x61, - 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x07, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0xda, 0x41, 0x13, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x83, 0x01, - 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, - 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, - 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x24, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, - 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x1a, 0x20, 0xca, 0x41, 0x1d, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, - 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x5d, 0x0a, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0xc4, 0x08, 0x0a, 0x05, 0x41, 0x64, 0x6d, 0x69, 0x6e, + 0x12, 0x5f, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x12, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0xb2, 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x6e, 0x67, 0x72, 0x75, 0x6e, 0x6e, 0x69, + 0x6e, 0x67, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x48, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x0d, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x65, 0xca, 0x41, 0x32, 0x0a, 0x17, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x4d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x8f, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, + 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x31, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x42, 0x11, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x69, - 0x67, 0x65, 0x65, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2f, 0x72, 0x70, 0x63, - 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, + 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2f, + 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xa2, 0x01, 0x0a, 0x0d, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x34, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, + 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x17, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x3a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0xda, 0x41, 0x12, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x2c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x12, 0xb4, + 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, + 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x22, + 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x32, 0x1d, 0x2f, 0x76, 0x31, 0x2f, 0x7b, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x2f, 0x2a, 0x7d, 0x3a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0xda, + 0x41, 0x13, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x83, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x2a, 0x15, 0x2f, + 0x76, 0x31, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x2f, 0x2a, 0x7d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x20, 0xca, 0x41, 0x1d, + 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, 0x70, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x42, 0x5d, 0x0a, + 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x6f, 0x75, + 0x64, 0x2e, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x42, 0x11, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x70, 0x69, 0x67, 0x65, 0x65, 0x2f, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2f, 0x72, 0x70, 0x63, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -611,38 +772,44 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescGZIP() []byt return file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDescData } -var file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_google_cloud_apigeeregistry_v1_admin_service_proto_goTypes = []interface{}{ - (*Status)(nil), // 0: google.cloud.apigeeregistry.v1.Status - (*ListProjectsRequest)(nil), // 1: google.cloud.apigeeregistry.v1.ListProjectsRequest - (*ListProjectsResponse)(nil), // 2: google.cloud.apigeeregistry.v1.ListProjectsResponse - (*GetProjectRequest)(nil), // 3: google.cloud.apigeeregistry.v1.GetProjectRequest - (*CreateProjectRequest)(nil), // 4: google.cloud.apigeeregistry.v1.CreateProjectRequest - (*UpdateProjectRequest)(nil), // 5: google.cloud.apigeeregistry.v1.UpdateProjectRequest - (*DeleteProjectRequest)(nil), // 6: google.cloud.apigeeregistry.v1.DeleteProjectRequest - (*Project)(nil), // 7: google.cloud.apigeeregistry.v1.Project - (*fieldmaskpb.FieldMask)(nil), // 8: google.protobuf.FieldMask - (*emptypb.Empty)(nil), // 9: google.protobuf.Empty + (*Status)(nil), // 0: google.cloud.apigeeregistry.v1.Status + (*MigrateDatabaseRequest)(nil), // 1: google.cloud.apigeeregistry.v1.MigrateDatabaseRequest + (*MigrateDatabaseMetadata)(nil), // 2: google.cloud.apigeeregistry.v1.MigrateDatabaseMetadata + (*MigrateDatabaseResponse)(nil), // 3: google.cloud.apigeeregistry.v1.MigrateDatabaseResponse + (*ListProjectsRequest)(nil), // 4: google.cloud.apigeeregistry.v1.ListProjectsRequest + (*ListProjectsResponse)(nil), // 5: google.cloud.apigeeregistry.v1.ListProjectsResponse + (*GetProjectRequest)(nil), // 6: google.cloud.apigeeregistry.v1.GetProjectRequest + (*CreateProjectRequest)(nil), // 7: google.cloud.apigeeregistry.v1.CreateProjectRequest + (*UpdateProjectRequest)(nil), // 8: google.cloud.apigeeregistry.v1.UpdateProjectRequest + (*DeleteProjectRequest)(nil), // 9: google.cloud.apigeeregistry.v1.DeleteProjectRequest + (*Project)(nil), // 10: google.cloud.apigeeregistry.v1.Project + (*fieldmaskpb.FieldMask)(nil), // 11: google.protobuf.FieldMask + (*emptypb.Empty)(nil), // 12: google.protobuf.Empty + (*longrunning.Operation)(nil), // 13: google.longrunning.Operation } var file_google_cloud_apigeeregistry_v1_admin_service_proto_depIdxs = []int32{ - 7, // 0: google.cloud.apigeeregistry.v1.ListProjectsResponse.projects:type_name -> google.cloud.apigeeregistry.v1.Project - 7, // 1: google.cloud.apigeeregistry.v1.CreateProjectRequest.project:type_name -> google.cloud.apigeeregistry.v1.Project - 7, // 2: google.cloud.apigeeregistry.v1.UpdateProjectRequest.project:type_name -> google.cloud.apigeeregistry.v1.Project - 8, // 3: google.cloud.apigeeregistry.v1.UpdateProjectRequest.update_mask:type_name -> google.protobuf.FieldMask - 9, // 4: google.cloud.apigeeregistry.v1.Admin.GetStatus:input_type -> google.protobuf.Empty - 1, // 5: google.cloud.apigeeregistry.v1.Admin.ListProjects:input_type -> google.cloud.apigeeregistry.v1.ListProjectsRequest - 3, // 6: google.cloud.apigeeregistry.v1.Admin.GetProject:input_type -> google.cloud.apigeeregistry.v1.GetProjectRequest - 4, // 7: google.cloud.apigeeregistry.v1.Admin.CreateProject:input_type -> google.cloud.apigeeregistry.v1.CreateProjectRequest - 5, // 8: google.cloud.apigeeregistry.v1.Admin.UpdateProject:input_type -> google.cloud.apigeeregistry.v1.UpdateProjectRequest - 6, // 9: google.cloud.apigeeregistry.v1.Admin.DeleteProject:input_type -> google.cloud.apigeeregistry.v1.DeleteProjectRequest - 0, // 10: google.cloud.apigeeregistry.v1.Admin.GetStatus:output_type -> google.cloud.apigeeregistry.v1.Status - 2, // 11: google.cloud.apigeeregistry.v1.Admin.ListProjects:output_type -> google.cloud.apigeeregistry.v1.ListProjectsResponse - 7, // 12: google.cloud.apigeeregistry.v1.Admin.GetProject:output_type -> google.cloud.apigeeregistry.v1.Project - 7, // 13: google.cloud.apigeeregistry.v1.Admin.CreateProject:output_type -> google.cloud.apigeeregistry.v1.Project - 7, // 14: google.cloud.apigeeregistry.v1.Admin.UpdateProject:output_type -> google.cloud.apigeeregistry.v1.Project - 9, // 15: google.cloud.apigeeregistry.v1.Admin.DeleteProject:output_type -> google.protobuf.Empty - 10, // [10:16] is the sub-list for method output_type - 4, // [4:10] is the sub-list for method input_type + 10, // 0: google.cloud.apigeeregistry.v1.ListProjectsResponse.projects:type_name -> google.cloud.apigeeregistry.v1.Project + 10, // 1: google.cloud.apigeeregistry.v1.CreateProjectRequest.project:type_name -> google.cloud.apigeeregistry.v1.Project + 10, // 2: google.cloud.apigeeregistry.v1.UpdateProjectRequest.project:type_name -> google.cloud.apigeeregistry.v1.Project + 11, // 3: google.cloud.apigeeregistry.v1.UpdateProjectRequest.update_mask:type_name -> google.protobuf.FieldMask + 12, // 4: google.cloud.apigeeregistry.v1.Admin.GetStatus:input_type -> google.protobuf.Empty + 1, // 5: google.cloud.apigeeregistry.v1.Admin.MigrateDatabase:input_type -> google.cloud.apigeeregistry.v1.MigrateDatabaseRequest + 4, // 6: google.cloud.apigeeregistry.v1.Admin.ListProjects:input_type -> google.cloud.apigeeregistry.v1.ListProjectsRequest + 6, // 7: google.cloud.apigeeregistry.v1.Admin.GetProject:input_type -> google.cloud.apigeeregistry.v1.GetProjectRequest + 7, // 8: google.cloud.apigeeregistry.v1.Admin.CreateProject:input_type -> google.cloud.apigeeregistry.v1.CreateProjectRequest + 8, // 9: google.cloud.apigeeregistry.v1.Admin.UpdateProject:input_type -> google.cloud.apigeeregistry.v1.UpdateProjectRequest + 9, // 10: google.cloud.apigeeregistry.v1.Admin.DeleteProject:input_type -> google.cloud.apigeeregistry.v1.DeleteProjectRequest + 0, // 11: google.cloud.apigeeregistry.v1.Admin.GetStatus:output_type -> google.cloud.apigeeregistry.v1.Status + 13, // 12: google.cloud.apigeeregistry.v1.Admin.MigrateDatabase:output_type -> google.longrunning.Operation + 5, // 13: google.cloud.apigeeregistry.v1.Admin.ListProjects:output_type -> google.cloud.apigeeregistry.v1.ListProjectsResponse + 10, // 14: google.cloud.apigeeregistry.v1.Admin.GetProject:output_type -> google.cloud.apigeeregistry.v1.Project + 10, // 15: google.cloud.apigeeregistry.v1.Admin.CreateProject:output_type -> google.cloud.apigeeregistry.v1.Project + 10, // 16: google.cloud.apigeeregistry.v1.Admin.UpdateProject:output_type -> google.cloud.apigeeregistry.v1.Project + 12, // 17: google.cloud.apigeeregistry.v1.Admin.DeleteProject:output_type -> google.protobuf.Empty + 11, // [11:18] is the sub-list for method output_type + 4, // [4:11] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name 4, // [4:4] is the sub-list for extension extendee 0, // [0:4] is the sub-list for field type_name @@ -668,7 +835,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProjectsRequest); i { + switch v := v.(*MigrateDatabaseRequest); i { case 0: return &v.state case 1: @@ -680,7 +847,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProjectsResponse); i { + switch v := v.(*MigrateDatabaseMetadata); i { case 0: return &v.state case 1: @@ -692,7 +859,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetProjectRequest); i { + switch v := v.(*MigrateDatabaseResponse); i { case 0: return &v.state case 1: @@ -704,7 +871,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateProjectRequest); i { + switch v := v.(*ListProjectsRequest); i { case 0: return &v.state case 1: @@ -716,7 +883,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateProjectRequest); i { + switch v := v.(*ListProjectsResponse); i { case 0: return &v.state case 1: @@ -728,6 +895,42 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { } } file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetProjectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateProjectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateProjectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_google_cloud_apigeeregistry_v1_admin_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteProjectRequest); i { case 0: return &v.state @@ -746,7 +949,7 @@ func file_google_cloud_apigeeregistry_v1_admin_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_google_cloud_apigeeregistry_v1_admin_service_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 10, NumExtensions: 0, NumServices: 1, }, diff --git a/rpc/admin_service_grpc.pb.go b/rpc/admin_service_grpc.pb.go index 8c0e760ab..87ba51bed 100644 --- a/rpc/admin_service_grpc.pb.go +++ b/rpc/admin_service_grpc.pb.go @@ -5,6 +5,7 @@ package rpc import ( context "context" + longrunning "google.golang.org/genproto/googleapis/longrunning" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -28,6 +29,8 @@ type AdminClient interface { // (-- api-linter: core::0131::http-uri-name=disabled // aip.dev/not-precedent: Not in the official API. --) GetStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*Status, error) + // MigrateDatabase attempts to migrate the database to the current schema. + MigrateDatabase(ctx context.Context, in *MigrateDatabaseRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) // ListProjects returns matching projects. // (-- api-linter: standard-methods=disabled --) // (-- api-linter: core::0132::method-signature=disabled @@ -66,6 +69,15 @@ func (c *adminClient) GetStatus(ctx context.Context, in *emptypb.Empty, opts ... return out, nil } +func (c *adminClient) MigrateDatabase(ctx context.Context, in *MigrateDatabaseRequest, opts ...grpc.CallOption) (*longrunning.Operation, error) { + out := new(longrunning.Operation) + err := c.cc.Invoke(ctx, "/google.cloud.apigeeregistry.v1.Admin/MigrateDatabase", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *adminClient) ListProjects(ctx context.Context, in *ListProjectsRequest, opts ...grpc.CallOption) (*ListProjectsResponse, error) { out := new(ListProjectsResponse) err := c.cc.Invoke(ctx, "/google.cloud.apigeeregistry.v1.Admin/ListProjects", in, out, opts...) @@ -123,6 +135,8 @@ type AdminServer interface { // (-- api-linter: core::0131::http-uri-name=disabled // aip.dev/not-precedent: Not in the official API. --) GetStatus(context.Context, *emptypb.Empty) (*Status, error) + // MigrateDatabase attempts to migrate the database to the current schema. + MigrateDatabase(context.Context, *MigrateDatabaseRequest) (*longrunning.Operation, error) // ListProjects returns matching projects. // (-- api-linter: standard-methods=disabled --) // (-- api-linter: core::0132::method-signature=disabled @@ -152,6 +166,9 @@ type UnimplementedAdminServer struct { func (UnimplementedAdminServer) GetStatus(context.Context, *emptypb.Empty) (*Status, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStatus not implemented") } +func (UnimplementedAdminServer) MigrateDatabase(context.Context, *MigrateDatabaseRequest) (*longrunning.Operation, error) { + return nil, status.Errorf(codes.Unimplemented, "method MigrateDatabase not implemented") +} func (UnimplementedAdminServer) ListProjects(context.Context, *ListProjectsRequest) (*ListProjectsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListProjects not implemented") } @@ -198,6 +215,24 @@ func _Admin_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(int return interceptor(ctx, in, info, handler) } +func _Admin_MigrateDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MigrateDatabaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AdminServer).MigrateDatabase(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.cloud.apigeeregistry.v1.Admin/MigrateDatabase", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AdminServer).MigrateDatabase(ctx, req.(*MigrateDatabaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Admin_ListProjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListProjectsRequest) if err := dec(in); err != nil { @@ -299,6 +334,10 @@ var Admin_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetStatus", Handler: _Admin_GetStatus_Handler, }, + { + MethodName: "MigrateDatabase", + Handler: _Admin_MigrateDatabase_Handler, + }, { MethodName: "ListProjects", Handler: _Admin_ListProjects_Handler, diff --git a/server/registry/actions_migrate_database.go b/server/registry/actions_migrate_database.go new file mode 100644 index 000000000..fa4bb209c --- /dev/null +++ b/server/registry/actions_migrate_database.go @@ -0,0 +1,53 @@ +// Copyright 2021 Google LLC. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package registry + +import ( + "context" + + "github.com/apigee/registry/rpc" + "google.golang.org/genproto/googleapis/longrunning" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/anypb" +) + +// MigrateDatabase handles the corresponding API request. +func (s *RegistryServer) MigrateDatabase(ctx context.Context, req *rpc.MigrateDatabaseRequest) (*longrunning.Operation, error) { + if req.Kind != "" && req.Kind != "auto" { + return nil, status.Errorf(codes.InvalidArgument, "unsupported migration kind %q", req.Kind) + } + db, err := s.getStorageClient(ctx) + if err != nil { + return nil, status.Error(codes.Unavailable, err.Error()) + } + defer db.Close() + + err = db.Migrate(req.Kind) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + metadata, _ := anypb.New(&rpc.MigrateDatabaseMetadata{}) + response, _ := anypb.New(&rpc.MigrateDatabaseResponse{ + Message: "OK", + }) + return &longrunning.Operation{ + Name: "migrate", + Metadata: metadata, + Done: true, + Result: &longrunning.Operation_Response{Response: response}, + }, nil +} diff --git a/server/registry/internal/storage/gorm/client.go b/server/registry/internal/storage/gorm/client.go index 49418ff7f..2efb35958 100644 --- a/server/registry/internal/storage/gorm/client.go +++ b/server/registry/internal/storage/gorm/client.go @@ -26,6 +26,20 @@ import ( "gorm.io/gorm" ) +// A complete list of entities used by the storage system +// and managed using gorm features. +var entities = []interface{}{ + &models.Project{}, + &models.Api{}, + &models.Version{}, + &models.Spec{}, + &models.SpecRevisionTag{}, + &models.Deployment{}, + &models.DeploymentRevisionTag{}, + &models.Artifact{}, + &models.Blob{}, +} + // Client represents a connection to a storage provider. type Client struct { db *gorm.DB @@ -118,17 +132,6 @@ func (c *Client) ensureTable(v interface{}) error { // EnsureTables ensures that all necessary tables exist in the database. func (c *Client) EnsureTables() error { - entities := []interface{}{ - &models.Project{}, - &models.Api{}, - &models.Version{}, - &models.Spec{}, - &models.SpecRevisionTag{}, - &models.Deployment{}, - &models.DeploymentRevisionTag{}, - &models.Artifact{}, - &models.Blob{}, - } for _, entity := range entities { if err := c.ensureTable(entity); err != nil { return err @@ -342,3 +345,7 @@ func (c *Client) GetRecentDeploymentRevisions(ctx context.Context, offset int32, _ = op.Scan(&v).Error return &Iterator{Client: c, Values: v, Index: 0} } + +func (c *Client) Migrate(kind string) error { + return c.db.AutoMigrate(entities...) +}