shao преди 2 дни
родител
ревизия
d9cd9b29bf

+ 2 - 2
dr_dcmtk_idl.proto

@@ -4,10 +4,10 @@ option go_package = "dr_dcmtk_pb/";
 
 package dr.dcmtk;
 
-message EmptyRequest {}
+import "google/protobuf/empty.proto";
 
 service Basic {
-  rpc SoftwareInfo (EmptyRequest) returns (SoftwareInfoReply) {}
+  rpc SoftwareInfo (google.protobuf.Empty) returns (SoftwareInfoReply) {}
 }
 
 message SoftwareInfoReply {

+ 22 - 58
dr_dcmtk_pb/dr_dcmtk_idl.pb.go

@@ -9,6 +9,7 @@ package dr_dcmtk_pb
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 	reflect "reflect"
 	sync "sync"
 	unsafe "unsafe"
@@ -21,42 +22,6 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-type EmptyRequest struct {
-	state         protoimpl.MessageState `protogen:"open.v1"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *EmptyRequest) Reset() {
-	*x = EmptyRequest{}
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *EmptyRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*EmptyRequest) ProtoMessage() {}
-
-func (x *EmptyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use EmptyRequest.ProtoReflect.Descriptor instead.
-func (*EmptyRequest) Descriptor() ([]byte, []int) {
-	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{0}
-}
-
 type SoftwareInfoReply struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
 	Module        string                 `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"`
@@ -69,7 +34,7 @@ type SoftwareInfoReply struct {
 
 func (x *SoftwareInfoReply) Reset() {
 	*x = SoftwareInfoReply{}
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[1]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[0]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -81,7 +46,7 @@ func (x *SoftwareInfoReply) String() string {
 func (*SoftwareInfoReply) ProtoMessage() {}
 
 func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[1]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[0]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -94,7 +59,7 @@ func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SoftwareInfoReply.ProtoReflect.Descriptor instead.
 func (*SoftwareInfoReply) Descriptor() ([]byte, []int) {
-	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{1}
+	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *SoftwareInfoReply) GetModule() string {
@@ -135,7 +100,7 @@ type UidRootRequest struct {
 
 func (x *UidRootRequest) Reset() {
 	*x = UidRootRequest{}
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[2]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[1]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -147,7 +112,7 @@ func (x *UidRootRequest) String() string {
 func (*UidRootRequest) ProtoMessage() {}
 
 func (x *UidRootRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[2]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[1]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -160,7 +125,7 @@ func (x *UidRootRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UidRootRequest.ProtoReflect.Descriptor instead.
 func (*UidRootRequest) Descriptor() ([]byte, []int) {
-	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{2}
+	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *UidRootRequest) GetUidRoot() string {
@@ -186,7 +151,7 @@ type UidReply struct {
 
 func (x *UidReply) Reset() {
 	*x = UidReply{}
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[3]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[2]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -198,7 +163,7 @@ func (x *UidReply) String() string {
 func (*UidReply) ProtoMessage() {}
 
 func (x *UidReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_dcmtk_idl_proto_msgTypes[3]
+	mi := &file_dr_dcmtk_idl_proto_msgTypes[2]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -211,7 +176,7 @@ func (x *UidReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use UidReply.ProtoReflect.Descriptor instead.
 func (*UidReply) Descriptor() ([]byte, []int) {
-	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{3}
+	return file_dr_dcmtk_idl_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *UidReply) GetInstanceUid() []string {
@@ -225,8 +190,7 @@ var File_dr_dcmtk_idl_proto protoreflect.FileDescriptor
 
 const file_dr_dcmtk_idl_proto_rawDesc = "" +
 	"\n" +
-	"\x12dr_dcmtk_idl.proto\x12\bdr.dcmtk\"\x0e\n" +
-	"\fEmptyRequest\"o\n" +
+	"\x12dr_dcmtk_idl.proto\x12\bdr.dcmtk\x1a\x1bgoogle/protobuf/empty.proto\"o\n" +
 	"\x11SoftwareInfoReply\x12\x16\n" +
 	"\x06module\x18\x01 \x01(\tR\x06module\x12\x12\n" +
 	"\x04desc\x18\x02 \x01(\tR\x04desc\x12\x14\n" +
@@ -238,7 +202,7 @@ const file_dr_dcmtk_idl_proto_rawDesc = "" +
 	"\bUidReply\x12!\n" +
 	"\finstance_uid\x18\x01 \x03(\tR\vinstanceUid2N\n" +
 	"\x05Basic\x12E\n" +
-	"\fSoftwareInfo\x12\x16.dr.dcmtk.EmptyRequest\x1a\x1b.dr.dcmtk.SoftwareInfoReply\"\x002Q\n" +
+	"\fSoftwareInfo\x12\x16.google.protobuf.Empty\x1a\x1b.dr.dcmtk.SoftwareInfoReply\"\x002Q\n" +
 	"\x03Dcm\x12J\n" +
 	"\x18GenerateUniqueIdentifier\x12\x18.dr.dcmtk.UidRootRequest\x1a\x12.dr.dcmtk.UidReply\"\x00B\x0eZ\fdr_dcmtk_pb/b\x06proto3"
 
@@ -254,18 +218,18 @@ func file_dr_dcmtk_idl_proto_rawDescGZIP() []byte {
 	return file_dr_dcmtk_idl_proto_rawDescData
 }
 
-var file_dr_dcmtk_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_dr_dcmtk_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
 var file_dr_dcmtk_idl_proto_goTypes = []any{
-	(*EmptyRequest)(nil),      // 0: dr.dcmtk.EmptyRequest
-	(*SoftwareInfoReply)(nil), // 1: dr.dcmtk.SoftwareInfoReply
-	(*UidRootRequest)(nil),    // 2: dr.dcmtk.UidRootRequest
-	(*UidReply)(nil),          // 3: dr.dcmtk.UidReply
+	(*SoftwareInfoReply)(nil), // 0: dr.dcmtk.SoftwareInfoReply
+	(*UidRootRequest)(nil),    // 1: dr.dcmtk.UidRootRequest
+	(*UidReply)(nil),          // 2: dr.dcmtk.UidReply
+	(*emptypb.Empty)(nil),     // 3: google.protobuf.Empty
 }
 var file_dr_dcmtk_idl_proto_depIdxs = []int32{
-	0, // 0: dr.dcmtk.Basic.SoftwareInfo:input_type -> dr.dcmtk.EmptyRequest
-	2, // 1: dr.dcmtk.Dcm.GenerateUniqueIdentifier:input_type -> dr.dcmtk.UidRootRequest
-	1, // 2: dr.dcmtk.Basic.SoftwareInfo:output_type -> dr.dcmtk.SoftwareInfoReply
-	3, // 3: dr.dcmtk.Dcm.GenerateUniqueIdentifier:output_type -> dr.dcmtk.UidReply
+	3, // 0: dr.dcmtk.Basic.SoftwareInfo:input_type -> google.protobuf.Empty
+	1, // 1: dr.dcmtk.Dcm.GenerateUniqueIdentifier:input_type -> dr.dcmtk.UidRootRequest
+	0, // 2: dr.dcmtk.Basic.SoftwareInfo:output_type -> dr.dcmtk.SoftwareInfoReply
+	2, // 3: dr.dcmtk.Dcm.GenerateUniqueIdentifier:output_type -> dr.dcmtk.UidReply
 	2, // [2:4] is the sub-list for method output_type
 	0, // [0:2] is the sub-list for method input_type
 	0, // [0:0] is the sub-list for extension type_name
@@ -284,7 +248,7 @@ func file_dr_dcmtk_idl_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_dr_dcmtk_idl_proto_rawDesc), len(file_dr_dcmtk_idl_proto_rawDesc)),
 			NumEnums:      0,
-			NumMessages:   4,
+			NumMessages:   3,
 			NumExtensions: 0,
 			NumServices:   2,
 		},

+ 7 - 6
dr_dcmtk_pb/dr_dcmtk_idl_grpc.pb.go

@@ -11,6 +11,7 @@ import (
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -26,7 +27,7 @@ const (
 //
 // 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 BasicClient interface {
-	SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
+	SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
 }
 
 type basicClient struct {
@@ -37,7 +38,7 @@ func NewBasicClient(cc grpc.ClientConnInterface) BasicClient {
 	return &basicClient{cc}
 }
 
-func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
+func (c *basicClient) SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
 	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
 	out := new(SoftwareInfoReply)
 	err := c.cc.Invoke(ctx, Basic_SoftwareInfo_FullMethodName, in, out, cOpts...)
@@ -51,7 +52,7 @@ func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts .
 // All implementations must embed UnimplementedBasicServer
 // for forward compatibility.
 type BasicServer interface {
-	SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error)
+	SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error)
 	mustEmbedUnimplementedBasicServer()
 }
 
@@ -62,7 +63,7 @@ type BasicServer interface {
 // pointer dereference when methods are called.
 type UnimplementedBasicServer struct{}
 
-func (UnimplementedBasicServer) SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error) {
+func (UnimplementedBasicServer) SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method SoftwareInfo not implemented")
 }
 func (UnimplementedBasicServer) mustEmbedUnimplementedBasicServer() {}
@@ -87,7 +88,7 @@ func RegisterBasicServer(s grpc.ServiceRegistrar, srv BasicServer) {
 }
 
 func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(EmptyRequest)
+	in := new(emptypb.Empty)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
@@ -99,7 +100,7 @@ func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(
 		FullMethod: Basic_SoftwareInfo_FullMethodName,
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BasicServer).SoftwareInfo(ctx, req.(*EmptyRequest))
+		return srv.(BasicServer).SoftwareInfo(ctx, req.(*emptypb.Empty))
 	}
 	return interceptor(ctx, in, info, handler)
 }

+ 2 - 1
dr_protocol_idl.proto

@@ -4,6 +4,7 @@ option go_package = "dr_protocol_pb/";
 
 package dr.protocol;
 
+import "google/protobuf/empty.proto";
 import "google/protobuf/struct.proto";
 
 message EmptyRequest {}
@@ -14,7 +15,7 @@ message IDRequest {
 }
 
 service Basic {
-  rpc SoftwareInfo (EmptyRequest) returns (SoftwareInfoReply) {}
+  rpc SoftwareInfo (google.protobuf.Empty) returns (SoftwareInfoReply) {}
 }
 
 message SoftwareInfoReply {

+ 7 - 5
dr_protocol_pb/dr_protocol_idl.pb.go

@@ -9,6 +9,7 @@ package dr_protocol_pb
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 	structpb "google.golang.org/protobuf/types/known/structpb"
 	reflect "reflect"
 	sync "sync"
@@ -1538,7 +1539,7 @@ var File_dr_protocol_idl_proto protoreflect.FileDescriptor
 
 const file_dr_protocol_idl_proto_rawDesc = "" +
 	"\n" +
-	"\x15dr_protocol_idl.proto\x12\vdr.protocol\x1a\x1cgoogle/protobuf/struct.proto\"\x0e\n" +
+	"\x15dr_protocol_idl.proto\x12\vdr.protocol\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x0e\n" +
 	"\fEmptyRequest\"]\n" +
 	"\tIDRequest\x12\x13\n" +
 	"\x02id\x18\x01 \x01(\rH\x00R\x02id\x88\x01\x01\x12$\n" +
@@ -1711,9 +1712,9 @@ const file_dr_protocol_idl_proto_rawDesc = "" +
 	"\n" +
 	"is_enabled\x18\v \x01(\bR\tisEnabled\x12\x18\n" +
 	"\aproduct\x18\f \x01(\tR\aproduct\x12$\n" +
-	"\x0eis_pre_install\x18\r \x01(\bR\fisPreInstall2T\n" +
-	"\x05Basic\x12K\n" +
-	"\fSoftwareInfo\x12\x19.dr.protocol.EmptyRequest\x1a\x1e.dr.protocol.SoftwareInfoReply\"\x002\xc0\x03\n" +
+	"\x0eis_pre_install\x18\r \x01(\bR\fisPreInstall2Q\n" +
+	"\x05Basic\x12H\n" +
+	"\fSoftwareInfo\x12\x16.google.protobuf.Empty\x1a\x1e.dr.protocol.SoftwareInfoReply\"\x002\xc0\x03\n" +
 	"\bProtocol\x12V\n" +
 	"\x12GetPatientTypeList\x12\x1f.dr.protocol.PatientTypeRequest\x1a\x1d.dr.protocol.PatientTypeReply\"\x00\x12M\n" +
 	"\x0fGetBodyPartList\x12\x1c.dr.protocol.BodyPartRequest\x1a\x1a.dr.protocol.BodyPartReply\"\x00\x12P\n" +
@@ -1757,6 +1758,7 @@ var file_dr_protocol_idl_proto_goTypes = []any{
 	(*AprSub)(nil),             // 16: dr.protocol.AprSub
 	(*AprReply)(nil),           // 17: dr.protocol.AprReply
 	(*structpb.Struct)(nil),    // 18: google.protobuf.Struct
+	(*emptypb.Empty)(nil),      // 19: google.protobuf.Empty
 }
 var file_dr_protocol_idl_proto_depIdxs = []int32{
 	4,  // 0: dr.protocol.PatientTypeReply.patient_type_list:type_name -> dr.protocol.PatientType
@@ -1766,7 +1768,7 @@ var file_dr_protocol_idl_proto_depIdxs = []int32{
 	13, // 4: dr.protocol.ViewReply.view_list:type_name -> dr.protocol.View
 	18, // 5: dr.protocol.AprSub.config_object:type_name -> google.protobuf.Struct
 	16, // 6: dr.protocol.AprReply.sub:type_name -> dr.protocol.AprSub
-	0,  // 7: dr.protocol.Basic.SoftwareInfo:input_type -> dr.protocol.EmptyRequest
+	19, // 7: dr.protocol.Basic.SoftwareInfo:input_type -> google.protobuf.Empty
 	3,  // 8: dr.protocol.Protocol.GetPatientTypeList:input_type -> dr.protocol.PatientTypeRequest
 	6,  // 9: dr.protocol.Protocol.GetBodyPartList:input_type -> dr.protocol.BodyPartRequest
 	9,  // 10: dr.protocol.Protocol.GetProcedureList:input_type -> dr.protocol.ProcedureRequest

+ 7 - 6
dr_protocol_pb/dr_protocol_idl_grpc.pb.go

@@ -11,6 +11,7 @@ import (
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -26,7 +27,7 @@ const (
 //
 // 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 BasicClient interface {
-	SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
+	SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
 }
 
 type basicClient struct {
@@ -37,7 +38,7 @@ func NewBasicClient(cc grpc.ClientConnInterface) BasicClient {
 	return &basicClient{cc}
 }
 
-func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
+func (c *basicClient) SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
 	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
 	out := new(SoftwareInfoReply)
 	err := c.cc.Invoke(ctx, Basic_SoftwareInfo_FullMethodName, in, out, cOpts...)
@@ -51,7 +52,7 @@ func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts .
 // All implementations must embed UnimplementedBasicServer
 // for forward compatibility.
 type BasicServer interface {
-	SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error)
+	SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error)
 	mustEmbedUnimplementedBasicServer()
 }
 
@@ -62,7 +63,7 @@ type BasicServer interface {
 // pointer dereference when methods are called.
 type UnimplementedBasicServer struct{}
 
-func (UnimplementedBasicServer) SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error) {
+func (UnimplementedBasicServer) SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method SoftwareInfo not implemented")
 }
 func (UnimplementedBasicServer) mustEmbedUnimplementedBasicServer() {}
@@ -87,7 +88,7 @@ func RegisterBasicServer(s grpc.ServiceRegistrar, srv BasicServer) {
 }
 
 func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(EmptyRequest)
+	in := new(emptypb.Empty)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
@@ -99,7 +100,7 @@ func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(
 		FullMethod: Basic_SoftwareInfo_FullMethodName,
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BasicServer).SoftwareInfo(ctx, req.(*EmptyRequest))
+		return srv.(BasicServer).SoftwareInfo(ctx, req.(*emptypb.Empty))
 	}
 	return interceptor(ctx, in, info, handler)
 }

+ 2 - 3
dr_resource_idl.proto

@@ -4,12 +4,11 @@ option go_package = "dr_resource_pb/";
 
 package dr.resource;
 
+import "google/protobuf/empty.proto";
 import "google/protobuf/struct.proto";
 
-message EmptyRequest {}
-
 service Basic {
-  rpc SoftwareInfo (EmptyRequest) returns (SoftwareInfoReply) {}
+  rpc SoftwareInfo (google.protobuf.Empty) returns (SoftwareInfoReply) {}
 }
 
 message SoftwareInfoReply {

+ 60 - 96
dr_resource_pb/dr_resource_idl.pb.go

@@ -9,6 +9,7 @@ package dr_resource_pb
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 	structpb "google.golang.org/protobuf/types/known/structpb"
 	reflect "reflect"
 	sync "sync"
@@ -22,42 +23,6 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-type EmptyRequest struct {
-	state         protoimpl.MessageState `protogen:"open.v1"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *EmptyRequest) Reset() {
-	*x = EmptyRequest{}
-	mi := &file_dr_resource_idl_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *EmptyRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*EmptyRequest) ProtoMessage() {}
-
-func (x *EmptyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use EmptyRequest.ProtoReflect.Descriptor instead.
-func (*EmptyRequest) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{0}
-}
-
 type SoftwareInfoReply struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
 	Module        string                 `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"`
@@ -70,7 +35,7 @@ type SoftwareInfoReply struct {
 
 func (x *SoftwareInfoReply) Reset() {
 	*x = SoftwareInfoReply{}
-	mi := &file_dr_resource_idl_proto_msgTypes[1]
+	mi := &file_dr_resource_idl_proto_msgTypes[0]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -82,7 +47,7 @@ func (x *SoftwareInfoReply) String() string {
 func (*SoftwareInfoReply) ProtoMessage() {}
 
 func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[1]
+	mi := &file_dr_resource_idl_proto_msgTypes[0]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -95,7 +60,7 @@ func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SoftwareInfoReply.ProtoReflect.Descriptor instead.
 func (*SoftwareInfoReply) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{1}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *SoftwareInfoReply) GetModule() string {
@@ -136,7 +101,7 @@ type OptionRequest struct {
 
 func (x *OptionRequest) Reset() {
 	*x = OptionRequest{}
-	mi := &file_dr_resource_idl_proto_msgTypes[2]
+	mi := &file_dr_resource_idl_proto_msgTypes[1]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -148,7 +113,7 @@ func (x *OptionRequest) String() string {
 func (*OptionRequest) ProtoMessage() {}
 
 func (x *OptionRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[2]
+	mi := &file_dr_resource_idl_proto_msgTypes[1]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -161,7 +126,7 @@ func (x *OptionRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use OptionRequest.ProtoReflect.Descriptor instead.
 func (*OptionRequest) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{2}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *OptionRequest) GetGroup() string {
@@ -187,7 +152,7 @@ type OptionReply struct {
 
 func (x *OptionReply) Reset() {
 	*x = OptionReply{}
-	mi := &file_dr_resource_idl_proto_msgTypes[3]
+	mi := &file_dr_resource_idl_proto_msgTypes[2]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -199,7 +164,7 @@ func (x *OptionReply) String() string {
 func (*OptionReply) ProtoMessage() {}
 
 func (x *OptionReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[3]
+	mi := &file_dr_resource_idl_proto_msgTypes[2]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -212,7 +177,7 @@ func (x *OptionReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use OptionReply.ProtoReflect.Descriptor instead.
 func (*OptionReply) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{3}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *OptionReply) GetOption() []*structpb.Struct {
@@ -232,7 +197,7 @@ type ConfigOptionListRequest struct {
 
 func (x *ConfigOptionListRequest) Reset() {
 	*x = ConfigOptionListRequest{}
-	mi := &file_dr_resource_idl_proto_msgTypes[4]
+	mi := &file_dr_resource_idl_proto_msgTypes[3]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -244,7 +209,7 @@ func (x *ConfigOptionListRequest) String() string {
 func (*ConfigOptionListRequest) ProtoMessage() {}
 
 func (x *ConfigOptionListRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[4]
+	mi := &file_dr_resource_idl_proto_msgTypes[3]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -257,7 +222,7 @@ func (x *ConfigOptionListRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigOptionListRequest.ProtoReflect.Descriptor instead.
 func (*ConfigOptionListRequest) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{4}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *ConfigOptionListRequest) GetFlag() string {
@@ -287,7 +252,7 @@ type ConfigOption struct {
 
 func (x *ConfigOption) Reset() {
 	*x = ConfigOption{}
-	mi := &file_dr_resource_idl_proto_msgTypes[5]
+	mi := &file_dr_resource_idl_proto_msgTypes[4]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -299,7 +264,7 @@ func (x *ConfigOption) String() string {
 func (*ConfigOption) ProtoMessage() {}
 
 func (x *ConfigOption) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[5]
+	mi := &file_dr_resource_idl_proto_msgTypes[4]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -312,7 +277,7 @@ func (x *ConfigOption) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigOption.ProtoReflect.Descriptor instead.
 func (*ConfigOption) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{5}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *ConfigOption) GetFlag() string {
@@ -359,7 +324,7 @@ type ConfigOptionListReply struct {
 
 func (x *ConfigOptionListReply) Reset() {
 	*x = ConfigOptionListReply{}
-	mi := &file_dr_resource_idl_proto_msgTypes[6]
+	mi := &file_dr_resource_idl_proto_msgTypes[5]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -371,7 +336,7 @@ func (x *ConfigOptionListReply) String() string {
 func (*ConfigOptionListReply) ProtoMessage() {}
 
 func (x *ConfigOptionListReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[6]
+	mi := &file_dr_resource_idl_proto_msgTypes[5]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -384,7 +349,7 @@ func (x *ConfigOptionListReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigOptionListReply.ProtoReflect.Descriptor instead.
 func (*ConfigOptionListReply) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{6}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *ConfigOptionListReply) GetConfigOption() []*ConfigOption {
@@ -407,7 +372,7 @@ type ConfigListRequest struct {
 
 func (x *ConfigListRequest) Reset() {
 	*x = ConfigListRequest{}
-	mi := &file_dr_resource_idl_proto_msgTypes[7]
+	mi := &file_dr_resource_idl_proto_msgTypes[6]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -419,7 +384,7 @@ func (x *ConfigListRequest) String() string {
 func (*ConfigListRequest) ProtoMessage() {}
 
 func (x *ConfigListRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[7]
+	mi := &file_dr_resource_idl_proto_msgTypes[6]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -432,7 +397,7 @@ func (x *ConfigListRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigListRequest.ProtoReflect.Descriptor instead.
 func (*ConfigListRequest) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{7}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *ConfigListRequest) GetFilter() isConfigListRequest_Filter {
@@ -492,7 +457,7 @@ type ConfigListResponse struct {
 
 func (x *ConfigListResponse) Reset() {
 	*x = ConfigListResponse{}
-	mi := &file_dr_resource_idl_proto_msgTypes[8]
+	mi := &file_dr_resource_idl_proto_msgTypes[7]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -504,7 +469,7 @@ func (x *ConfigListResponse) String() string {
 func (*ConfigListResponse) ProtoMessage() {}
 
 func (x *ConfigListResponse) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[8]
+	mi := &file_dr_resource_idl_proto_msgTypes[7]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -517,7 +482,7 @@ func (x *ConfigListResponse) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigListResponse.ProtoReflect.Descriptor instead.
 func (*ConfigListResponse) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{8}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *ConfigListResponse) GetKey() string {
@@ -585,7 +550,7 @@ type ConfigItemRequest struct {
 
 func (x *ConfigItemRequest) Reset() {
 	*x = ConfigItemRequest{}
-	mi := &file_dr_resource_idl_proto_msgTypes[9]
+	mi := &file_dr_resource_idl_proto_msgTypes[8]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -597,7 +562,7 @@ func (x *ConfigItemRequest) String() string {
 func (*ConfigItemRequest) ProtoMessage() {}
 
 func (x *ConfigItemRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_resource_idl_proto_msgTypes[9]
+	mi := &file_dr_resource_idl_proto_msgTypes[8]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -610,7 +575,7 @@ func (x *ConfigItemRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ConfigItemRequest.ProtoReflect.Descriptor instead.
 func (*ConfigItemRequest) Descriptor() ([]byte, []int) {
-	return file_dr_resource_idl_proto_rawDescGZIP(), []int{9}
+	return file_dr_resource_idl_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *ConfigItemRequest) GetItems() map[string]string {
@@ -624,8 +589,7 @@ var File_dr_resource_idl_proto protoreflect.FileDescriptor
 
 const file_dr_resource_idl_proto_rawDesc = "" +
 	"\n" +
-	"\x15dr_resource_idl.proto\x12\vdr.resource\x1a\x1cgoogle/protobuf/struct.proto\"\x0e\n" +
-	"\fEmptyRequest\"o\n" +
+	"\x15dr_resource_idl.proto\x12\vdr.resource\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1cgoogle/protobuf/struct.proto\"o\n" +
 	"\x11SoftwareInfoReply\x12\x16\n" +
 	"\x06module\x18\x01 \x01(\tR\x06module\x12\x12\n" +
 	"\x04desc\x18\x02 \x01(\tR\x04desc\x12\x14\n" +
@@ -670,9 +634,9 @@ const file_dr_resource_idl_proto_rawDesc = "" +
 	"\n" +
 	"ItemsEntry\x12\x10\n" +
 	"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
-	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x012T\n" +
-	"\x05Basic\x12K\n" +
-	"\fSoftwareInfo\x12\x19.dr.resource.EmptyRequest\x1a\x1e.dr.resource.SoftwareInfoReply\"\x002\xd7\x02\n" +
+	"\x05value\x18\x02 \x01(\tR\x05value:\x028\x012Q\n" +
+	"\x05Basic\x12H\n" +
+	"\fSoftwareInfo\x12\x16.google.protobuf.Empty\x1a\x1e.dr.resource.SoftwareInfoReply\"\x002\xd7\x02\n" +
 	"\x06Config\x12D\n" +
 	"\n" +
 	"GetOptions\x12\x1a.dr.resource.OptionRequest\x1a\x18.dr.resource.OptionReply\"\x00\x12^\n" +
@@ -693,35 +657,35 @@ func file_dr_resource_idl_proto_rawDescGZIP() []byte {
 	return file_dr_resource_idl_proto_rawDescData
 }
 
-var file_dr_resource_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
+var file_dr_resource_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
 var file_dr_resource_idl_proto_goTypes = []any{
-	(*EmptyRequest)(nil),            // 0: dr.resource.EmptyRequest
-	(*SoftwareInfoReply)(nil),       // 1: dr.resource.SoftwareInfoReply
-	(*OptionRequest)(nil),           // 2: dr.resource.OptionRequest
-	(*OptionReply)(nil),             // 3: dr.resource.OptionReply
-	(*ConfigOptionListRequest)(nil), // 4: dr.resource.ConfigOptionListRequest
-	(*ConfigOption)(nil),            // 5: dr.resource.ConfigOption
-	(*ConfigOptionListReply)(nil),   // 6: dr.resource.ConfigOptionListReply
-	(*ConfigListRequest)(nil),       // 7: dr.resource.ConfigListRequest
-	(*ConfigListResponse)(nil),      // 8: dr.resource.ConfigListResponse
-	(*ConfigItemRequest)(nil),       // 9: dr.resource.ConfigItemRequest
-	nil,                             // 10: dr.resource.ConfigItemRequest.ItemsEntry
-	(*structpb.Struct)(nil),         // 11: google.protobuf.Struct
+	(*SoftwareInfoReply)(nil),       // 0: dr.resource.SoftwareInfoReply
+	(*OptionRequest)(nil),           // 1: dr.resource.OptionRequest
+	(*OptionReply)(nil),             // 2: dr.resource.OptionReply
+	(*ConfigOptionListRequest)(nil), // 3: dr.resource.ConfigOptionListRequest
+	(*ConfigOption)(nil),            // 4: dr.resource.ConfigOption
+	(*ConfigOptionListReply)(nil),   // 5: dr.resource.ConfigOptionListReply
+	(*ConfigListRequest)(nil),       // 6: dr.resource.ConfigListRequest
+	(*ConfigListResponse)(nil),      // 7: dr.resource.ConfigListResponse
+	(*ConfigItemRequest)(nil),       // 8: dr.resource.ConfigItemRequest
+	nil,                             // 9: dr.resource.ConfigItemRequest.ItemsEntry
+	(*structpb.Struct)(nil),         // 10: google.protobuf.Struct
+	(*emptypb.Empty)(nil),           // 11: google.protobuf.Empty
 }
 var file_dr_resource_idl_proto_depIdxs = []int32{
-	11, // 0: dr.resource.OptionReply.option:type_name -> google.protobuf.Struct
-	5,  // 1: dr.resource.ConfigOptionListReply.configOption:type_name -> dr.resource.ConfigOption
-	10, // 2: dr.resource.ConfigItemRequest.items:type_name -> dr.resource.ConfigItemRequest.ItemsEntry
-	0,  // 3: dr.resource.Basic.SoftwareInfo:input_type -> dr.resource.EmptyRequest
-	2,  // 4: dr.resource.Config.GetOptions:input_type -> dr.resource.OptionRequest
-	4,  // 5: dr.resource.Config.ConfigOptionList:input_type -> dr.resource.ConfigOptionListRequest
-	7,  // 6: dr.resource.Config.ConfigList:input_type -> dr.resource.ConfigListRequest
-	9,  // 7: dr.resource.Config.UpdateConfigItems:input_type -> dr.resource.ConfigItemRequest
-	1,  // 8: dr.resource.Basic.SoftwareInfo:output_type -> dr.resource.SoftwareInfoReply
-	3,  // 9: dr.resource.Config.GetOptions:output_type -> dr.resource.OptionReply
-	6,  // 10: dr.resource.Config.ConfigOptionList:output_type -> dr.resource.ConfigOptionListReply
-	8,  // 11: dr.resource.Config.ConfigList:output_type -> dr.resource.ConfigListResponse
-	8,  // 12: dr.resource.Config.UpdateConfigItems:output_type -> dr.resource.ConfigListResponse
+	10, // 0: dr.resource.OptionReply.option:type_name -> google.protobuf.Struct
+	4,  // 1: dr.resource.ConfigOptionListReply.configOption:type_name -> dr.resource.ConfigOption
+	9,  // 2: dr.resource.ConfigItemRequest.items:type_name -> dr.resource.ConfigItemRequest.ItemsEntry
+	11, // 3: dr.resource.Basic.SoftwareInfo:input_type -> google.protobuf.Empty
+	1,  // 4: dr.resource.Config.GetOptions:input_type -> dr.resource.OptionRequest
+	3,  // 5: dr.resource.Config.ConfigOptionList:input_type -> dr.resource.ConfigOptionListRequest
+	6,  // 6: dr.resource.Config.ConfigList:input_type -> dr.resource.ConfigListRequest
+	8,  // 7: dr.resource.Config.UpdateConfigItems:input_type -> dr.resource.ConfigItemRequest
+	0,  // 8: dr.resource.Basic.SoftwareInfo:output_type -> dr.resource.SoftwareInfoReply
+	2,  // 9: dr.resource.Config.GetOptions:output_type -> dr.resource.OptionReply
+	5,  // 10: dr.resource.Config.ConfigOptionList:output_type -> dr.resource.ConfigOptionListReply
+	7,  // 11: dr.resource.Config.ConfigList:output_type -> dr.resource.ConfigListResponse
+	7,  // 12: dr.resource.Config.UpdateConfigItems:output_type -> dr.resource.ConfigListResponse
 	8,  // [8:13] is the sub-list for method output_type
 	3,  // [3:8] is the sub-list for method input_type
 	3,  // [3:3] is the sub-list for extension type_name
@@ -734,7 +698,7 @@ func file_dr_resource_idl_proto_init() {
 	if File_dr_resource_idl_proto != nil {
 		return
 	}
-	file_dr_resource_idl_proto_msgTypes[7].OneofWrappers = []any{
+	file_dr_resource_idl_proto_msgTypes[6].OneofWrappers = []any{
 		(*ConfigListRequest_Group)(nil),
 		(*ConfigListRequest_Key)(nil),
 	}
@@ -744,7 +708,7 @@ func file_dr_resource_idl_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_dr_resource_idl_proto_rawDesc), len(file_dr_resource_idl_proto_rawDesc)),
 			NumEnums:      0,
-			NumMessages:   11,
+			NumMessages:   10,
 			NumExtensions: 0,
 			NumServices:   2,
 		},

+ 7 - 6
dr_resource_pb/dr_resource_idl_grpc.pb.go

@@ -11,6 +11,7 @@ import (
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -26,7 +27,7 @@ const (
 //
 // 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 BasicClient interface {
-	SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
+	SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
 }
 
 type basicClient struct {
@@ -37,7 +38,7 @@ func NewBasicClient(cc grpc.ClientConnInterface) BasicClient {
 	return &basicClient{cc}
 }
 
-func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
+func (c *basicClient) SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
 	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
 	out := new(SoftwareInfoReply)
 	err := c.cc.Invoke(ctx, Basic_SoftwareInfo_FullMethodName, in, out, cOpts...)
@@ -51,7 +52,7 @@ func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts .
 // All implementations must embed UnimplementedBasicServer
 // for forward compatibility.
 type BasicServer interface {
-	SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error)
+	SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error)
 	mustEmbedUnimplementedBasicServer()
 }
 
@@ -62,7 +63,7 @@ type BasicServer interface {
 // pointer dereference when methods are called.
 type UnimplementedBasicServer struct{}
 
-func (UnimplementedBasicServer) SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error) {
+func (UnimplementedBasicServer) SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method SoftwareInfo not implemented")
 }
 func (UnimplementedBasicServer) mustEmbedUnimplementedBasicServer() {}
@@ -87,7 +88,7 @@ func RegisterBasicServer(s grpc.ServiceRegistrar, srv BasicServer) {
 }
 
 func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(EmptyRequest)
+	in := new(emptypb.Empty)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
@@ -99,7 +100,7 @@ func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(
 		FullMethod: Basic_SoftwareInfo_FullMethodName,
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BasicServer).SoftwareInfo(ctx, req.(*EmptyRequest))
+		return srv.(BasicServer).SoftwareInfo(ctx, req.(*emptypb.Empty))
 	}
 	return interceptor(ctx, in, info, handler)
 }

+ 14 - 3
dr_study_idl.proto

@@ -4,18 +4,17 @@ option go_package = "dr_study_pb/";
 
 package dr.study;
 
+import "google/protobuf/empty.proto";
 import "google/protobuf/timestamp.proto";
 import "google/protobuf/struct.proto";
 
-message EmptyRequest {}
-
 message IDRequest {
   optional uint32 id = 1;
   optional string instance_id = 2;
 }
 
 service Basic {
-  rpc SoftwareInfo (EmptyRequest) returns (SoftwareInfoReply) {}
+  rpc SoftwareInfo (google.protobuf.Empty) returns (SoftwareInfoReply) {}
 }
 
 message SoftwareInfoReply {
@@ -28,6 +27,10 @@ message SoftwareInfoReply {
 service Study {
   rpc CreateStudy (StudyRequest) returns (StudyReply) {}
   rpc GetStudy (IDRequest) returns (StudyReply) {}
+  rpc CreateSeries (ViewRequest) returns (SeriesReply) {}
+  rpc CopyImage (IDRequest) returns (SeriesReply) {}
+  rpc DeleteImage (IDRequest) returns (google.protobuf.Empty) {}
+  rpc SortImage (SortRequest) returns (google.protobuf.Empty) {}
 }
 
 message ViewRequest {
@@ -139,3 +142,11 @@ message StudyReply {
   string product = 44;
   repeated Series series = 45;
 }
+
+message SeriesReply {
+  repeated Series series = 1;
+}
+
+message SortRequest {
+  repeated string sop_instance_id = 1;
+}

+ 169 - 98
dr_study_pb/dr_study_idl.pb.go

@@ -9,6 +9,7 @@ package dr_study_pb
 import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 	structpb "google.golang.org/protobuf/types/known/structpb"
 	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
 	reflect "reflect"
@@ -23,42 +24,6 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
-type EmptyRequest struct {
-	state         protoimpl.MessageState `protogen:"open.v1"`
-	unknownFields protoimpl.UnknownFields
-	sizeCache     protoimpl.SizeCache
-}
-
-func (x *EmptyRequest) Reset() {
-	*x = EmptyRequest{}
-	mi := &file_dr_study_idl_proto_msgTypes[0]
-	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-	ms.StoreMessageInfo(mi)
-}
-
-func (x *EmptyRequest) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*EmptyRequest) ProtoMessage() {}
-
-func (x *EmptyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[0]
-	if x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use EmptyRequest.ProtoReflect.Descriptor instead.
-func (*EmptyRequest) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{0}
-}
-
 type IDRequest struct {
 	state         protoimpl.MessageState `protogen:"open.v1"`
 	Id            *uint32                `protobuf:"varint,1,opt,name=id,proto3,oneof" json:"id,omitempty"`
@@ -69,7 +34,7 @@ type IDRequest struct {
 
 func (x *IDRequest) Reset() {
 	*x = IDRequest{}
-	mi := &file_dr_study_idl_proto_msgTypes[1]
+	mi := &file_dr_study_idl_proto_msgTypes[0]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -81,7 +46,7 @@ func (x *IDRequest) String() string {
 func (*IDRequest) ProtoMessage() {}
 
 func (x *IDRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[1]
+	mi := &file_dr_study_idl_proto_msgTypes[0]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -94,7 +59,7 @@ func (x *IDRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use IDRequest.ProtoReflect.Descriptor instead.
 func (*IDRequest) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{1}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{0}
 }
 
 func (x *IDRequest) GetId() uint32 {
@@ -123,7 +88,7 @@ type SoftwareInfoReply struct {
 
 func (x *SoftwareInfoReply) Reset() {
 	*x = SoftwareInfoReply{}
-	mi := &file_dr_study_idl_proto_msgTypes[2]
+	mi := &file_dr_study_idl_proto_msgTypes[1]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -135,7 +100,7 @@ func (x *SoftwareInfoReply) String() string {
 func (*SoftwareInfoReply) ProtoMessage() {}
 
 func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[2]
+	mi := &file_dr_study_idl_proto_msgTypes[1]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -148,7 +113,7 @@ func (x *SoftwareInfoReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use SoftwareInfoReply.ProtoReflect.Descriptor instead.
 func (*SoftwareInfoReply) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{2}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *SoftwareInfoReply) GetModule() string {
@@ -189,7 +154,7 @@ type ViewRequest struct {
 
 func (x *ViewRequest) Reset() {
 	*x = ViewRequest{}
-	mi := &file_dr_study_idl_proto_msgTypes[3]
+	mi := &file_dr_study_idl_proto_msgTypes[2]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -201,7 +166,7 @@ func (x *ViewRequest) String() string {
 func (*ViewRequest) ProtoMessage() {}
 
 func (x *ViewRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[3]
+	mi := &file_dr_study_idl_proto_msgTypes[2]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -214,7 +179,7 @@ func (x *ViewRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ViewRequest.ProtoReflect.Descriptor instead.
 func (*ViewRequest) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{3}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{2}
 }
 
 func (x *ViewRequest) GetViewId() string {
@@ -260,7 +225,7 @@ type StudyRequest struct {
 
 func (x *StudyRequest) Reset() {
 	*x = StudyRequest{}
-	mi := &file_dr_study_idl_proto_msgTypes[4]
+	mi := &file_dr_study_idl_proto_msgTypes[3]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -272,7 +237,7 @@ func (x *StudyRequest) String() string {
 func (*StudyRequest) ProtoMessage() {}
 
 func (x *StudyRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[4]
+	mi := &file_dr_study_idl_proto_msgTypes[3]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -285,7 +250,7 @@ func (x *StudyRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StudyRequest.ProtoReflect.Descriptor instead.
 func (*StudyRequest) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{4}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{3}
 }
 
 func (x *StudyRequest) GetAccessionNumber() string {
@@ -458,7 +423,7 @@ type Image struct {
 
 func (x *Image) Reset() {
 	*x = Image{}
-	mi := &file_dr_study_idl_proto_msgTypes[5]
+	mi := &file_dr_study_idl_proto_msgTypes[4]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -470,7 +435,7 @@ func (x *Image) String() string {
 func (*Image) ProtoMessage() {}
 
 func (x *Image) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[5]
+	mi := &file_dr_study_idl_proto_msgTypes[4]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -483,7 +448,7 @@ func (x *Image) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Image.ProtoReflect.Descriptor instead.
 func (*Image) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{5}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{4}
 }
 
 func (x *Image) GetSopInstanceId() string {
@@ -611,7 +576,7 @@ type Series struct {
 
 func (x *Series) Reset() {
 	*x = Series{}
-	mi := &file_dr_study_idl_proto_msgTypes[6]
+	mi := &file_dr_study_idl_proto_msgTypes[5]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -623,7 +588,7 @@ func (x *Series) String() string {
 func (*Series) ProtoMessage() {}
 
 func (x *Series) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[6]
+	mi := &file_dr_study_idl_proto_msgTypes[5]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -636,7 +601,7 @@ func (x *Series) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Series.ProtoReflect.Descriptor instead.
 func (*Series) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{6}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{5}
 }
 
 func (x *Series) GetSeriesInstanceUid() string {
@@ -776,7 +741,7 @@ type StudyReply struct {
 
 func (x *StudyReply) Reset() {
 	*x = StudyReply{}
-	mi := &file_dr_study_idl_proto_msgTypes[7]
+	mi := &file_dr_study_idl_proto_msgTypes[6]
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 	ms.StoreMessageInfo(mi)
 }
@@ -788,7 +753,7 @@ func (x *StudyReply) String() string {
 func (*StudyReply) ProtoMessage() {}
 
 func (x *StudyReply) ProtoReflect() protoreflect.Message {
-	mi := &file_dr_study_idl_proto_msgTypes[7]
+	mi := &file_dr_study_idl_proto_msgTypes[6]
 	if x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -801,7 +766,7 @@ func (x *StudyReply) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use StudyReply.ProtoReflect.Descriptor instead.
 func (*StudyReply) Descriptor() ([]byte, []int) {
-	return file_dr_study_idl_proto_rawDescGZIP(), []int{7}
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *StudyReply) GetStudyInstanceUid() string {
@@ -1119,12 +1084,99 @@ func (x *StudyReply) GetSeries() []*Series {
 	return nil
 }
 
+type SeriesReply struct {
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	Series        []*Series              `protobuf:"bytes,1,rep,name=series,proto3" json:"series,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *SeriesReply) Reset() {
+	*x = SeriesReply{}
+	mi := &file_dr_study_idl_proto_msgTypes[7]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *SeriesReply) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SeriesReply) ProtoMessage() {}
+
+func (x *SeriesReply) ProtoReflect() protoreflect.Message {
+	mi := &file_dr_study_idl_proto_msgTypes[7]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SeriesReply.ProtoReflect.Descriptor instead.
+func (*SeriesReply) Descriptor() ([]byte, []int) {
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *SeriesReply) GetSeries() []*Series {
+	if x != nil {
+		return x.Series
+	}
+	return nil
+}
+
+type SortRequest struct {
+	state         protoimpl.MessageState `protogen:"open.v1"`
+	SopInstanceId []string               `protobuf:"bytes,1,rep,name=sop_instance_id,json=sopInstanceId,proto3" json:"sop_instance_id,omitempty"`
+	unknownFields protoimpl.UnknownFields
+	sizeCache     protoimpl.SizeCache
+}
+
+func (x *SortRequest) Reset() {
+	*x = SortRequest{}
+	mi := &file_dr_study_idl_proto_msgTypes[8]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *SortRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SortRequest) ProtoMessage() {}
+
+func (x *SortRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_dr_study_idl_proto_msgTypes[8]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SortRequest.ProtoReflect.Descriptor instead.
+func (*SortRequest) Descriptor() ([]byte, []int) {
+	return file_dr_study_idl_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *SortRequest) GetSopInstanceId() []string {
+	if x != nil {
+		return x.SopInstanceId
+	}
+	return nil
+}
+
 var File_dr_study_idl_proto protoreflect.FileDescriptor
 
 const file_dr_study_idl_proto_rawDesc = "" +
 	"\n" +
-	"\x12dr_study_idl.proto\x12\bdr.study\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x0e\n" +
-	"\fEmptyRequest\"]\n" +
+	"\x12dr_study_idl.proto\x12\bdr.study\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"]\n" +
 	"\tIDRequest\x12\x13\n" +
 	"\x02id\x18\x01 \x01(\rH\x00R\x02id\x88\x01\x01\x12$\n" +
 	"\vinstance_id\x18\x02 \x01(\tH\x01R\n" +
@@ -1260,12 +1312,20 @@ const file_dr_study_idl_proto_rawDesc = "" +
 	"\acomment\x18* \x01(\tR\acomment\x12\x12\n" +
 	"\x04sort\x18+ \x01(\x05R\x04sort\x12\x18\n" +
 	"\aproduct\x18, \x01(\tR\aproduct\x12(\n" +
-	"\x06series\x18- \x03(\v2\x10.dr.study.SeriesR\x06series2N\n" +
+	"\x06series\x18- \x03(\v2\x10.dr.study.SeriesR\x06series\"7\n" +
+	"\vSeriesReply\x12(\n" +
+	"\x06series\x18\x01 \x03(\v2\x10.dr.study.SeriesR\x06series\"5\n" +
+	"\vSortRequest\x12&\n" +
+	"\x0fsop_instance_id\x18\x01 \x03(\tR\rsopInstanceId2N\n" +
 	"\x05Basic\x12E\n" +
-	"\fSoftwareInfo\x12\x16.dr.study.EmptyRequest\x1a\x1b.dr.study.SoftwareInfoReply\"\x002\x7f\n" +
+	"\fSoftwareInfo\x12\x16.google.protobuf.Empty\x1a\x1b.dr.study.SoftwareInfoReply\"\x002\xf6\x02\n" +
 	"\x05Study\x12=\n" +
 	"\vCreateStudy\x12\x16.dr.study.StudyRequest\x1a\x14.dr.study.StudyReply\"\x00\x127\n" +
-	"\bGetStudy\x12\x13.dr.study.IDRequest\x1a\x14.dr.study.StudyReply\"\x00B\x0eZ\fdr_study_pb/b\x06proto3"
+	"\bGetStudy\x12\x13.dr.study.IDRequest\x1a\x14.dr.study.StudyReply\"\x00\x12>\n" +
+	"\fCreateSeries\x12\x15.dr.study.ViewRequest\x1a\x15.dr.study.SeriesReply\"\x00\x129\n" +
+	"\tCopyImage\x12\x13.dr.study.IDRequest\x1a\x15.dr.study.SeriesReply\"\x00\x12<\n" +
+	"\vDeleteImage\x12\x13.dr.study.IDRequest\x1a\x16.google.protobuf.Empty\"\x00\x12<\n" +
+	"\tSortImage\x12\x15.dr.study.SortRequest\x1a\x16.google.protobuf.Empty\"\x00B\x0eZ\fdr_study_pb/b\x06proto3"
 
 var (
 	file_dr_study_idl_proto_rawDescOnce sync.Once
@@ -1279,43 +1339,54 @@ func file_dr_study_idl_proto_rawDescGZIP() []byte {
 	return file_dr_study_idl_proto_rawDescData
 }
 
-var file_dr_study_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_dr_study_idl_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
 var file_dr_study_idl_proto_goTypes = []any{
-	(*EmptyRequest)(nil),          // 0: dr.study.EmptyRequest
-	(*IDRequest)(nil),             // 1: dr.study.IDRequest
-	(*SoftwareInfoReply)(nil),     // 2: dr.study.SoftwareInfoReply
-	(*ViewRequest)(nil),           // 3: dr.study.ViewRequest
-	(*StudyRequest)(nil),          // 4: dr.study.StudyRequest
-	(*Image)(nil),                 // 5: dr.study.Image
-	(*Series)(nil),                // 6: dr.study.Series
-	(*StudyReply)(nil),            // 7: dr.study.StudyReply
-	(*timestamppb.Timestamp)(nil), // 8: google.protobuf.Timestamp
-	(*structpb.Struct)(nil),       // 9: google.protobuf.Struct
+	(*IDRequest)(nil),             // 0: dr.study.IDRequest
+	(*SoftwareInfoReply)(nil),     // 1: dr.study.SoftwareInfoReply
+	(*ViewRequest)(nil),           // 2: dr.study.ViewRequest
+	(*StudyRequest)(nil),          // 3: dr.study.StudyRequest
+	(*Image)(nil),                 // 4: dr.study.Image
+	(*Series)(nil),                // 5: dr.study.Series
+	(*StudyReply)(nil),            // 6: dr.study.StudyReply
+	(*SeriesReply)(nil),           // 7: dr.study.SeriesReply
+	(*SortRequest)(nil),           // 8: dr.study.SortRequest
+	(*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp
+	(*structpb.Struct)(nil),       // 10: google.protobuf.Struct
+	(*emptypb.Empty)(nil),         // 11: google.protobuf.Empty
 }
 var file_dr_study_idl_proto_depIdxs = []int32{
-	8,  // 0: dr.study.StudyRequest.patient_dob:type_name -> google.protobuf.Timestamp
-	3,  // 1: dr.study.StudyRequest.views:type_name -> dr.study.ViewRequest
-	9,  // 2: dr.study.Image.acquisition_context:type_name -> google.protobuf.Struct
-	9,  // 3: dr.study.Image.img_proc_context:type_name -> google.protobuf.Struct
-	8,  // 4: dr.study.Series.performed_datetime:type_name -> google.protobuf.Timestamp
-	5,  // 5: dr.study.Series.images:type_name -> dr.study.Image
-	8,  // 6: dr.study.StudyReply.patient_dob:type_name -> google.protobuf.Timestamp
-	8,  // 7: dr.study.StudyReply.admitting_time:type_name -> google.protobuf.Timestamp
-	8,  // 8: dr.study.StudyReply.study_start_datetime:type_name -> google.protobuf.Timestamp
-	8,  // 9: dr.study.StudyReply.study_end_datetime:type_name -> google.protobuf.Timestamp
-	8,  // 10: dr.study.StudyReply.scheduled_procedure_step_start_date:type_name -> google.protobuf.Timestamp
-	6,  // 11: dr.study.StudyReply.series:type_name -> dr.study.Series
-	0,  // 12: dr.study.Basic.SoftwareInfo:input_type -> dr.study.EmptyRequest
-	4,  // 13: dr.study.Study.CreateStudy:input_type -> dr.study.StudyRequest
-	1,  // 14: dr.study.Study.GetStudy:input_type -> dr.study.IDRequest
-	2,  // 15: dr.study.Basic.SoftwareInfo:output_type -> dr.study.SoftwareInfoReply
-	7,  // 16: dr.study.Study.CreateStudy:output_type -> dr.study.StudyReply
-	7,  // 17: dr.study.Study.GetStudy:output_type -> dr.study.StudyReply
-	15, // [15:18] is the sub-list for method output_type
-	12, // [12:15] is the sub-list for method input_type
-	12, // [12:12] is the sub-list for extension type_name
-	12, // [12:12] is the sub-list for extension extendee
-	0,  // [0:12] is the sub-list for field type_name
+	9,  // 0: dr.study.StudyRequest.patient_dob:type_name -> google.protobuf.Timestamp
+	2,  // 1: dr.study.StudyRequest.views:type_name -> dr.study.ViewRequest
+	10, // 2: dr.study.Image.acquisition_context:type_name -> google.protobuf.Struct
+	10, // 3: dr.study.Image.img_proc_context:type_name -> google.protobuf.Struct
+	9,  // 4: dr.study.Series.performed_datetime:type_name -> google.protobuf.Timestamp
+	4,  // 5: dr.study.Series.images:type_name -> dr.study.Image
+	9,  // 6: dr.study.StudyReply.patient_dob:type_name -> google.protobuf.Timestamp
+	9,  // 7: dr.study.StudyReply.admitting_time:type_name -> google.protobuf.Timestamp
+	9,  // 8: dr.study.StudyReply.study_start_datetime:type_name -> google.protobuf.Timestamp
+	9,  // 9: dr.study.StudyReply.study_end_datetime:type_name -> google.protobuf.Timestamp
+	9,  // 10: dr.study.StudyReply.scheduled_procedure_step_start_date:type_name -> google.protobuf.Timestamp
+	5,  // 11: dr.study.StudyReply.series:type_name -> dr.study.Series
+	5,  // 12: dr.study.SeriesReply.series:type_name -> dr.study.Series
+	11, // 13: dr.study.Basic.SoftwareInfo:input_type -> google.protobuf.Empty
+	3,  // 14: dr.study.Study.CreateStudy:input_type -> dr.study.StudyRequest
+	0,  // 15: dr.study.Study.GetStudy:input_type -> dr.study.IDRequest
+	2,  // 16: dr.study.Study.CreateSeries:input_type -> dr.study.ViewRequest
+	0,  // 17: dr.study.Study.CopyImage:input_type -> dr.study.IDRequest
+	0,  // 18: dr.study.Study.DeleteImage:input_type -> dr.study.IDRequest
+	8,  // 19: dr.study.Study.SortImage:input_type -> dr.study.SortRequest
+	1,  // 20: dr.study.Basic.SoftwareInfo:output_type -> dr.study.SoftwareInfoReply
+	6,  // 21: dr.study.Study.CreateStudy:output_type -> dr.study.StudyReply
+	6,  // 22: dr.study.Study.GetStudy:output_type -> dr.study.StudyReply
+	7,  // 23: dr.study.Study.CreateSeries:output_type -> dr.study.SeriesReply
+	7,  // 24: dr.study.Study.CopyImage:output_type -> dr.study.SeriesReply
+	11, // 25: dr.study.Study.DeleteImage:output_type -> google.protobuf.Empty
+	11, // 26: dr.study.Study.SortImage:output_type -> google.protobuf.Empty
+	20, // [20:27] is the sub-list for method output_type
+	13, // [13:20] is the sub-list for method input_type
+	13, // [13:13] is the sub-list for extension type_name
+	13, // [13:13] is the sub-list for extension extendee
+	0,  // [0:13] is the sub-list for field type_name
 }
 
 func init() { file_dr_study_idl_proto_init() }
@@ -1323,14 +1394,14 @@ func file_dr_study_idl_proto_init() {
 	if File_dr_study_idl_proto != nil {
 		return
 	}
-	file_dr_study_idl_proto_msgTypes[1].OneofWrappers = []any{}
+	file_dr_study_idl_proto_msgTypes[0].OneofWrappers = []any{}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_dr_study_idl_proto_rawDesc), len(file_dr_study_idl_proto_rawDesc)),
 			NumEnums:      0,
-			NumMessages:   8,
+			NumMessages:   9,
 			NumExtensions: 0,
 			NumServices:   2,
 		},

+ 161 - 8
dr_study_pb/dr_study_idl_grpc.pb.go

@@ -11,6 +11,7 @@ import (
 	grpc "google.golang.org/grpc"
 	codes "google.golang.org/grpc/codes"
 	status "google.golang.org/grpc/status"
+	emptypb "google.golang.org/protobuf/types/known/emptypb"
 )
 
 // This is a compile-time assertion to ensure that this generated file
@@ -26,7 +27,7 @@ const (
 //
 // 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 BasicClient interface {
-	SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
+	SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error)
 }
 
 type basicClient struct {
@@ -37,7 +38,7 @@ func NewBasicClient(cc grpc.ClientConnInterface) BasicClient {
 	return &basicClient{cc}
 }
 
-func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
+func (c *basicClient) SoftwareInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SoftwareInfoReply, error) {
 	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
 	out := new(SoftwareInfoReply)
 	err := c.cc.Invoke(ctx, Basic_SoftwareInfo_FullMethodName, in, out, cOpts...)
@@ -51,7 +52,7 @@ func (c *basicClient) SoftwareInfo(ctx context.Context, in *EmptyRequest, opts .
 // All implementations must embed UnimplementedBasicServer
 // for forward compatibility.
 type BasicServer interface {
-	SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error)
+	SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error)
 	mustEmbedUnimplementedBasicServer()
 }
 
@@ -62,7 +63,7 @@ type BasicServer interface {
 // pointer dereference when methods are called.
 type UnimplementedBasicServer struct{}
 
-func (UnimplementedBasicServer) SoftwareInfo(context.Context, *EmptyRequest) (*SoftwareInfoReply, error) {
+func (UnimplementedBasicServer) SoftwareInfo(context.Context, *emptypb.Empty) (*SoftwareInfoReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method SoftwareInfo not implemented")
 }
 func (UnimplementedBasicServer) mustEmbedUnimplementedBasicServer() {}
@@ -87,7 +88,7 @@ func RegisterBasicServer(s grpc.ServiceRegistrar, srv BasicServer) {
 }
 
 func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(EmptyRequest)
+	in := new(emptypb.Empty)
 	if err := dec(in); err != nil {
 		return nil, err
 	}
@@ -99,7 +100,7 @@ func _Basic_SoftwareInfo_Handler(srv interface{}, ctx context.Context, dec func(
 		FullMethod: Basic_SoftwareInfo_FullMethodName,
 	}
 	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(BasicServer).SoftwareInfo(ctx, req.(*EmptyRequest))
+		return srv.(BasicServer).SoftwareInfo(ctx, req.(*emptypb.Empty))
 	}
 	return interceptor(ctx, in, info, handler)
 }
@@ -121,8 +122,12 @@ var Basic_ServiceDesc = grpc.ServiceDesc{
 }
 
 const (
-	Study_CreateStudy_FullMethodName = "/dr.study.Study/CreateStudy"
-	Study_GetStudy_FullMethodName    = "/dr.study.Study/GetStudy"
+	Study_CreateStudy_FullMethodName  = "/dr.study.Study/CreateStudy"
+	Study_GetStudy_FullMethodName     = "/dr.study.Study/GetStudy"
+	Study_CreateSeries_FullMethodName = "/dr.study.Study/CreateSeries"
+	Study_CopyImage_FullMethodName    = "/dr.study.Study/CopyImage"
+	Study_DeleteImage_FullMethodName  = "/dr.study.Study/DeleteImage"
+	Study_SortImage_FullMethodName    = "/dr.study.Study/SortImage"
 )
 
 // StudyClient is the client API for Study service.
@@ -131,6 +136,10 @@ const (
 type StudyClient interface {
 	CreateStudy(ctx context.Context, in *StudyRequest, opts ...grpc.CallOption) (*StudyReply, error)
 	GetStudy(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*StudyReply, error)
+	CreateSeries(ctx context.Context, in *ViewRequest, opts ...grpc.CallOption) (*SeriesReply, error)
+	CopyImage(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*SeriesReply, error)
+	DeleteImage(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	SortImage(ctx context.Context, in *SortRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
 }
 
 type studyClient struct {
@@ -161,12 +170,56 @@ func (c *studyClient) GetStudy(ctx context.Context, in *IDRequest, opts ...grpc.
 	return out, nil
 }
 
+func (c *studyClient) CreateSeries(ctx context.Context, in *ViewRequest, opts ...grpc.CallOption) (*SeriesReply, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(SeriesReply)
+	err := c.cc.Invoke(ctx, Study_CreateSeries_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *studyClient) CopyImage(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*SeriesReply, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(SeriesReply)
+	err := c.cc.Invoke(ctx, Study_CopyImage_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *studyClient) DeleteImage(ctx context.Context, in *IDRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, Study_DeleteImage_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *studyClient) SortImage(ctx context.Context, in *SortRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, Study_SortImage_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // StudyServer is the server API for Study service.
 // All implementations must embed UnimplementedStudyServer
 // for forward compatibility.
 type StudyServer interface {
 	CreateStudy(context.Context, *StudyRequest) (*StudyReply, error)
 	GetStudy(context.Context, *IDRequest) (*StudyReply, error)
+	CreateSeries(context.Context, *ViewRequest) (*SeriesReply, error)
+	CopyImage(context.Context, *IDRequest) (*SeriesReply, error)
+	DeleteImage(context.Context, *IDRequest) (*emptypb.Empty, error)
+	SortImage(context.Context, *SortRequest) (*emptypb.Empty, error)
 	mustEmbedUnimplementedStudyServer()
 }
 
@@ -183,6 +236,18 @@ func (UnimplementedStudyServer) CreateStudy(context.Context, *StudyRequest) (*St
 func (UnimplementedStudyServer) GetStudy(context.Context, *IDRequest) (*StudyReply, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method GetStudy not implemented")
 }
+func (UnimplementedStudyServer) CreateSeries(context.Context, *ViewRequest) (*SeriesReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CreateSeries not implemented")
+}
+func (UnimplementedStudyServer) CopyImage(context.Context, *IDRequest) (*SeriesReply, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method CopyImage not implemented")
+}
+func (UnimplementedStudyServer) DeleteImage(context.Context, *IDRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method DeleteImage not implemented")
+}
+func (UnimplementedStudyServer) SortImage(context.Context, *SortRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method SortImage not implemented")
+}
 func (UnimplementedStudyServer) mustEmbedUnimplementedStudyServer() {}
 func (UnimplementedStudyServer) testEmbeddedByValue()               {}
 
@@ -240,6 +305,78 @@ func _Study_GetStudy_Handler(srv interface{}, ctx context.Context, dec func(inte
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Study_CreateSeries_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ViewRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(StudyServer).CreateSeries(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Study_CreateSeries_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(StudyServer).CreateSeries(ctx, req.(*ViewRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Study_CopyImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(IDRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(StudyServer).CopyImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Study_CopyImage_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(StudyServer).CopyImage(ctx, req.(*IDRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Study_DeleteImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(IDRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(StudyServer).DeleteImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Study_DeleteImage_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(StudyServer).DeleteImage(ctx, req.(*IDRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Study_SortImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(SortRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(StudyServer).SortImage(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Study_SortImage_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(StudyServer).SortImage(ctx, req.(*SortRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // Study_ServiceDesc is the grpc.ServiceDesc for Study service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -255,6 +392,22 @@ var Study_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "GetStudy",
 			Handler:    _Study_GetStudy_Handler,
 		},
+		{
+			MethodName: "CreateSeries",
+			Handler:    _Study_CreateSeries_Handler,
+		},
+		{
+			MethodName: "CopyImage",
+			Handler:    _Study_CopyImage_Handler,
+		},
+		{
+			MethodName: "DeleteImage",
+			Handler:    _Study_DeleteImage_Handler,
+		},
+		{
+			MethodName: "SortImage",
+			Handler:    _Study_SortImage_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "dr_study_idl.proto",