From 0be254a13f10e1c2fed10128b686620aea3c5820 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 11 Dec 2023 15:18:16 +0800 Subject: [PATCH 01/14] upgrade package and rtc convert --- go.mod | 4 +- go.sum | 8 +- tools/up35/pkg/convert.go | 227 +++++++++++ .../pkg/internal/rtc/mongo/mgo/meeting.go | 86 +++++ .../rtc/mongo/mgo/meeting_invitation.go | 76 ++++ .../internal/rtc/mongo/mgo/meeting_record.go | 32 ++ .../up35/pkg/internal/rtc/mongo/mgo/signal.go | 89 +++++ .../rtc/mongo/mgo/signal_invitation.go | 78 ++++ .../pkg/internal/rtc/mongo/table/meeting.go | 51 +++ .../pkg/internal/rtc/mongo/table/signal.go | 73 ++++ tools/up35/pkg/internal/rtc/mysql/meeting.go | 40 ++ tools/up35/pkg/internal/rtc/mysql/signal.go | 43 +++ tools/up35/pkg/pkg.go | 206 ++++++++++ tools/up35/up35.go | 352 +----------------- 14 files changed, 1009 insertions(+), 356 deletions(-) create mode 100644 tools/up35/pkg/convert.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/mgo/meeting.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/mgo/meeting_invitation.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/mgo/meeting_record.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/mgo/signal.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/mgo/signal_invitation.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/table/meeting.go create mode 100644 tools/up35/pkg/internal/rtc/mongo/table/signal.go create mode 100644 tools/up35/pkg/internal/rtc/mysql/meeting.go create mode 100644 tools/up35/pkg/internal/rtc/mysql/signal.go create mode 100644 tools/up35/pkg/pkg.go diff --git a/go.mod b/go.mod index 6cf2089de6..ec547aa625 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.19 require ( firebase.google.com/go v3.13.0+incompatible + github.com/OpenIMSDK/protocol v0.0.33 + github.com/OpenIMSDK/tools v0.0.20 github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/dtm-labs/rockscache v0.1.1 github.com/gin-gonic/gin v1.9.1 @@ -33,8 +35,6 @@ require github.com/google/uuid v1.3.1 require ( github.com/IBM/sarama v1.41.3 - github.com/OpenIMSDK/protocol v0.0.31 - github.com/OpenIMSDK/tools v0.0.18 github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/go-redis/redis v6.15.9+incompatible github.com/redis/go-redis/v9 v9.2.1 diff --git a/go.sum b/go.sum index 2f9198c9fe..71565c8693 100644 --- a/go.sum +++ b/go.sum @@ -18,10 +18,10 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= -github.com/OpenIMSDK/protocol v0.0.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE= -github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= -github.com/OpenIMSDK/tools v0.0.18 h1:h3CvKB90DNd2aIJcOQ99cqgeW6C0na0PzR1TNsfxwL0= -github.com/OpenIMSDK/tools v0.0.18/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= +github.com/OpenIMSDK/protocol v0.0.33 h1:T07KWD0jt7IRlrYRujCa+eXmfgcSi8sRgLL8t2ZlHQA= +github.com/OpenIMSDK/protocol v0.0.33/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= +github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k= +github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= diff --git a/tools/up35/pkg/convert.go b/tools/up35/pkg/convert.go new file mode 100644 index 0000000000..91fdb474e0 --- /dev/null +++ b/tools/up35/pkg/convert.go @@ -0,0 +1,227 @@ +package pkg + +import ( + mongoModel "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + mysqlModel "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3" + mongoModelRtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + mysqlModelRtc "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mysql" + "time" +) + +type convert struct{} + +func (convert) User(v mysqlModel.UserModel) mongoModel.UserModel { + return mongoModel.UserModel{ + UserID: v.UserID, + Nickname: v.Nickname, + FaceURL: v.FaceURL, + Ex: v.Ex, + AppMangerLevel: v.AppMangerLevel, + GlobalRecvMsgOpt: v.GlobalRecvMsgOpt, + CreateTime: v.CreateTime, + } +} + +func (convert) Friend(v mysqlModel.FriendModel) mongoModel.FriendModel { + return mongoModel.FriendModel{ + OwnerUserID: v.OwnerUserID, + FriendUserID: v.FriendUserID, + Remark: v.Remark, + CreateTime: v.CreateTime, + AddSource: v.AddSource, + OperatorUserID: v.OperatorUserID, + Ex: v.Ex, + } +} + +func (convert) FriendRequest(v mysqlModel.FriendRequestModel) mongoModel.FriendRequestModel { + return mongoModel.FriendRequestModel{ + FromUserID: v.FromUserID, + ToUserID: v.ToUserID, + HandleResult: v.HandleResult, + ReqMsg: v.ReqMsg, + CreateTime: v.CreateTime, + HandlerUserID: v.HandlerUserID, + HandleMsg: v.HandleMsg, + HandleTime: v.HandleTime, + Ex: v.Ex, + } +} + +func (convert) Black(v mysqlModel.BlackModel) mongoModel.BlackModel { + return mongoModel.BlackModel{ + OwnerUserID: v.OwnerUserID, + BlockUserID: v.BlockUserID, + CreateTime: v.CreateTime, + AddSource: v.AddSource, + OperatorUserID: v.OperatorUserID, + Ex: v.Ex, + } +} + +func (convert) Group(v mysqlModel.GroupModel) mongoModel.GroupModel { + return mongoModel.GroupModel{ + GroupID: v.GroupID, + GroupName: v.GroupName, + Notification: v.Notification, + Introduction: v.Introduction, + FaceURL: v.FaceURL, + CreateTime: v.CreateTime, + Ex: v.Ex, + Status: v.Status, + CreatorUserID: v.CreatorUserID, + GroupType: v.GroupType, + NeedVerification: v.NeedVerification, + LookMemberInfo: v.LookMemberInfo, + ApplyMemberFriend: v.ApplyMemberFriend, + NotificationUpdateTime: v.NotificationUpdateTime, + NotificationUserID: v.NotificationUserID, + } +} + +func (convert) GroupMember(v mysqlModel.GroupMemberModel) mongoModel.GroupMemberModel { + return mongoModel.GroupMemberModel{ + GroupID: v.GroupID, + UserID: v.UserID, + Nickname: v.Nickname, + FaceURL: v.FaceURL, + RoleLevel: v.RoleLevel, + JoinTime: v.JoinTime, + JoinSource: v.JoinSource, + InviterUserID: v.InviterUserID, + OperatorUserID: v.OperatorUserID, + MuteEndTime: v.MuteEndTime, + Ex: v.Ex, + } +} + +func (convert) GroupRequest(v mysqlModel.GroupRequestModel) mongoModel.GroupRequestModel { + return mongoModel.GroupRequestModel{ + UserID: v.UserID, + GroupID: v.GroupID, + HandleResult: v.HandleResult, + ReqMsg: v.ReqMsg, + HandledMsg: v.HandledMsg, + ReqTime: v.ReqTime, + HandleUserID: v.HandleUserID, + HandledTime: v.HandledTime, + JoinSource: v.JoinSource, + InviterUserID: v.InviterUserID, + Ex: v.Ex, + } +} + +func (convert) Conversation(v mysqlModel.ConversationModel) mongoModel.ConversationModel { + return mongoModel.ConversationModel{ + OwnerUserID: v.OwnerUserID, + ConversationID: v.ConversationID, + ConversationType: v.ConversationType, + UserID: v.UserID, + GroupID: v.GroupID, + RecvMsgOpt: v.RecvMsgOpt, + IsPinned: v.IsPinned, + IsPrivateChat: v.IsPrivateChat, + BurnDuration: v.BurnDuration, + GroupAtType: v.GroupAtType, + AttachedInfo: v.AttachedInfo, + Ex: v.Ex, + MaxSeq: v.MaxSeq, + MinSeq: v.MinSeq, + CreateTime: v.CreateTime, + IsMsgDestruct: v.IsMsgDestruct, + MsgDestructTime: v.MsgDestructTime, + LatestMsgDestructTime: v.LatestMsgDestructTime, + } +} + +func (convert) Object(engine string) func(v mysqlModel.ObjectModel) mongoModel.ObjectModel { + return func(v mysqlModel.ObjectModel) mongoModel.ObjectModel { + return mongoModel.ObjectModel{ + Name: v.Name, + UserID: v.UserID, + Hash: v.Hash, + Engine: engine, + Key: v.Key, + Size: v.Size, + ContentType: v.ContentType, + Group: v.Cause, + CreateTime: v.CreateTime, + } + } +} + +func (convert) Log(v mysqlModel.Log) mongoModel.LogModel { + return mongoModel.LogModel{ + LogID: v.LogID, + Platform: v.Platform, + UserID: v.UserID, + CreateTime: v.CreateTime, + Url: v.Url, + FileName: v.FileName, + SystemType: v.SystemType, + Version: v.Version, + Ex: v.Ex, + } +} + +func (convert) SignalModel(v mysqlModelRtc.SignalModel) mongoModelRtc.SignalModel { + return mongoModelRtc.SignalModel{ + SID: v.SID, + InviterUserID: v.InviterUserID, + CustomData: v.CustomData, + GroupID: v.GroupID, + RoomID: v.RoomID, + Timeout: v.Timeout, + MediaType: v.MediaType, + PlatformID: v.PlatformID, + SessionType: v.SessionType, + InitiateTime: v.InitiateTime, + EndTime: v.EndTime, + FileURL: v.FileURL, + Title: v.Title, + Desc: v.Desc, + Ex: v.Ex, + IOSPushSound: v.IOSPushSound, + IOSBadgeCount: v.IOSBadgeCount, + SignalInfo: v.SignalInfo, + } +} + +func (convert) SignalInvitationModel(v mysqlModelRtc.SignalInvitationModel) mongoModelRtc.SignalInvitationModel { + return mongoModelRtc.SignalInvitationModel{ + SID: v.SID, + UserID: v.UserID, + Status: v.Status, + InitiateTime: v.InitiateTime, + HandleTime: v.HandleTime, + } +} + +func (convert) Meeting(v mysqlModelRtc.MeetingInfo) mongoModelRtc.MeetingInfo { + return mongoModelRtc.MeetingInfo{ + RoomID: v.RoomID, + MeetingName: v.MeetingName, + HostUserID: v.HostUserID, + Status: v.Status, + StartTime: time.Unix(v.StartTime, 0), + EndTime: time.Unix(v.EndTime, 0), + CreateTime: v.CreateTime, + Ex: v.Ex, + } +} + +func (convert) MeetingInvitationInfo(v mysqlModelRtc.MeetingInvitationInfo) mongoModelRtc.MeetingInvitationInfo { + return mongoModelRtc.MeetingInvitationInfo{ + RoomID: v.RoomID, + UserID: v.UserID, + CreateTime: v.CreateTime, + } +} + +func (convert) MeetingVideoRecord(v mysqlModelRtc.MeetingVideoRecord) mongoModelRtc.MeetingVideoRecord { + return mongoModelRtc.MeetingVideoRecord{ + RoomID: v.RoomID, + FileURL: v.FileURL, + CreateTime: v.CreateTime, + } +} diff --git a/tools/up35/pkg/internal/rtc/mongo/mgo/meeting.go b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting.go new file mode 100644 index 0000000000..e3bab7af93 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting.go @@ -0,0 +1,86 @@ +package mgo + +import ( + "context" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewMeeting(db *mongo.Database) (table.MeetingInterface, error) { + coll := db.Collection("meeting") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "room_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "host_user_id", Value: 1}, + }, + }, + { + Keys: bson.D{ + {Key: "create_time", Value: -1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &meeting{coll: coll}, nil +} + +type meeting struct { + coll *mongo.Collection +} + +func (x *meeting) Find(ctx context.Context, roomIDs []string) ([]*table.MeetingInfo, error) { + return mgoutil.Find[*table.MeetingInfo](ctx, x.coll, bson.M{"room_id": bson.M{"$in": roomIDs}}) +} + +func (x *meeting) CreateMeetingInfo(ctx context.Context, meetingInfo *table.MeetingInfo) error { + return mgoutil.InsertMany(ctx, x.coll, []*table.MeetingInfo{meetingInfo}) +} + +func (x *meeting) UpdateMeetingInfo(ctx context.Context, roomID string, update map[string]any) error { + if len(update) == 0 { + return nil + } + return mgoutil.UpdateOne(ctx, x.coll, bson.M{"room_id": roomID}, bson.M{"$set": update}, false) +} + +func (x *meeting) GetUnCompleteMeetingIDList(ctx context.Context, roomIDs []string) ([]string, error) { + if len(roomIDs) == 0 { + return nil, nil + } + return mgoutil.Find[string](ctx, x.coll, bson.M{"room_id": bson.M{"$in": roomIDs}, "status": 0}, options.Find().SetProjection(bson.M{"_id": 0, "room_id": 1})) +} + +func (x *meeting) Delete(ctx context.Context, roomIDs []string) error { + return mgoutil.DeleteMany(ctx, x.coll, bson.M{"room_id": bson.M{"$in": roomIDs}}) +} + +func (x *meeting) GetMeetingRecords(ctx context.Context, hostUserID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []*table.MeetingInfo, error) { + var and []bson.M + if hostUserID != "" { + and = append(and, bson.M{"host_user_id": hostUserID}) + } + if !startTime.IsZero() { + and = append(and, bson.M{"create_time": bson.M{"$gte": startTime}}) + } + if !endTime.IsZero() { + and = append(and, bson.M{"create_time": bson.M{"$lte": endTime}}) + } + filter := bson.M{} + if len(and) > 0 { + filter["$and"] = and + } + return mgoutil.FindPage[*table.MeetingInfo](ctx, x.coll, filter, pagination, options.Find().SetSort(bson.M{"create_time": -1})) +} diff --git a/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_invitation.go b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_invitation.go new file mode 100644 index 0000000000..5286ffa954 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_invitation.go @@ -0,0 +1,76 @@ +package mgo + +import ( + "context" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "github.com/OpenIMSDK/tools/utils" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewMeetingInvitation(db *mongo.Database) (table.MeetingInvitationInterface, error) { + coll := db.Collection("meeting_invitation") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "room_id", Value: 1}, + {Key: "user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "create_time", Value: -1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &meetingInvitation{coll: coll}, nil +} + +type meetingInvitation struct { + coll *mongo.Collection +} + +func (x *meetingInvitation) FindUserIDs(ctx context.Context, roomID string) ([]string, error) { + return mgoutil.Find[string](ctx, x.coll, bson.M{"room_id": roomID}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1})) +} + +func (x *meetingInvitation) CreateMeetingInvitationInfo(ctx context.Context, roomID string, inviteeUserIDs []string) error { + now := time.Now() + return mgoutil.InsertMany(ctx, x.coll, utils.Slice(inviteeUserIDs, func(userID string) *table.MeetingInvitationInfo { + return &table.MeetingInvitationInfo{ + RoomID: roomID, + UserID: userID, + CreateTime: now, + } + })) +} + +func (x *meetingInvitation) GetUserInvitedMeetingIDs(ctx context.Context, userID string) (meetingIDs []string, err error) { + fiveDaysAgo := time.Now().AddDate(0, 0, -5) + return mgoutil.Find[string](ctx, x.coll, bson.M{"user_id": userID, "create_time": bson.M{"$gte": fiveDaysAgo}}, options.Find().SetSort(bson.M{"create_time": -1}).SetProjection(bson.M{"_id": 0, "room_id": 1})) +} + +func (x *meetingInvitation) Delete(ctx context.Context, roomIDs []string) error { + return mgoutil.DeleteMany(ctx, x.coll, bson.M{"room_id": bson.M{"$in": roomIDs}}) +} + +func (x *meetingInvitation) GetMeetingRecords(ctx context.Context, joinedUserID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []string, error) { + var and []bson.M + and = append(and, bson.M{"user_id": joinedUserID}) + if !startTime.IsZero() { + and = append(and, bson.M{"create_time": bson.M{"$gte": startTime}}) + } + if !endTime.IsZero() { + and = append(and, bson.M{"create_time": bson.M{"$lte": endTime}}) + } + opt := options.Find().SetSort(bson.M{"create_time": -1}).SetProjection(bson.M{"_id": 0, "room_id": 1}) + return mgoutil.FindPage[string](ctx, x.coll, bson.M{"$and": and}, pagination, opt) +} diff --git a/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_record.go b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_record.go new file mode 100644 index 0000000000..90fc9cdca0 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/mgo/meeting_record.go @@ -0,0 +1,32 @@ +package mgo + +import ( + "context" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" +) + +func NewMeetingRecord(db *mongo.Database) (table.MeetingRecordInterface, error) { + coll := db.Collection("meeting_record") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "room_id", Value: 1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &meetingRecord{coll: coll}, nil +} + +type meetingRecord struct { + coll *mongo.Collection +} + +func (x *meetingRecord) CreateMeetingVideoRecord(ctx context.Context, meetingVideoRecord *table.MeetingVideoRecord) error { + return mgoutil.InsertMany(ctx, x.coll, []*table.MeetingVideoRecord{meetingVideoRecord}) +} diff --git a/tools/up35/pkg/internal/rtc/mongo/mgo/signal.go b/tools/up35/pkg/internal/rtc/mongo/mgo/signal.go new file mode 100644 index 0000000000..0c18790079 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/mgo/signal.go @@ -0,0 +1,89 @@ +package mgo + +import ( + "context" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewSignal(db *mongo.Database) (table.SignalInterface, error) { + coll := db.Collection("signal") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "sid", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "inviter_user_id", Value: 1}, + }, + }, + { + Keys: bson.D{ + {Key: "initiate_time", Value: -1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &signal{coll: coll}, nil +} + +type signal struct { + coll *mongo.Collection +} + +func (x *signal) Find(ctx context.Context, sids []string) ([]*table.SignalModel, error) { + return mgoutil.Find[*table.SignalModel](ctx, x.coll, bson.M{"sid": bson.M{"$in": sids}}) +} + +func (x *signal) CreateSignal(ctx context.Context, signalModel *table.SignalModel) error { + return mgoutil.InsertMany(ctx, x.coll, []*table.SignalModel{signalModel}) +} + +func (x *signal) Update(ctx context.Context, sid string, update map[string]any) error { + if len(update) == 0 { + return nil + } + return mgoutil.UpdateOne(ctx, x.coll, bson.M{"sid": sid}, bson.M{"$set": update}, false) +} + +func (x *signal) UpdateSignalFileURL(ctx context.Context, sID, fileURL string) error { + return x.Update(ctx, sID, map[string]any{"file_url": fileURL}) +} + +func (x *signal) UpdateSignalEndTime(ctx context.Context, sID string, endTime time.Time) error { + return x.Update(ctx, sID, map[string]any{"end_time": endTime}) +} + +func (x *signal) Delete(ctx context.Context, sids []string) error { + if len(sids) == 0 { + return nil + } + return mgoutil.DeleteMany(ctx, x.coll, bson.M{"sid": bson.M{"$in": sids}}) +} + +func (x *signal) PageSignal(ctx context.Context, sesstionType int32, sendID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []*table.SignalModel, error) { + var and []bson.M + if !startTime.IsZero() { + and = append(and, bson.M{"initiate_time": bson.M{"$gte": startTime}}) + } + if !endTime.IsZero() { + and = append(and, bson.M{"initiate_time": bson.M{"$lte": endTime}}) + } + if sesstionType != 0 { + and = append(and, bson.M{"sesstion_type": sesstionType}) + } + if sendID != "" { + and = append(and, bson.M{"inviter_user_id": sendID}) + } + return mgoutil.FindPage[*table.SignalModel](ctx, x.coll, bson.M{"$and": and}, pagination, options.Find().SetSort(bson.M{"initiate_time": -1})) +} diff --git a/tools/up35/pkg/internal/rtc/mongo/mgo/signal_invitation.go b/tools/up35/pkg/internal/rtc/mongo/mgo/signal_invitation.go new file mode 100644 index 0000000000..274f2f11f9 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/mgo/signal_invitation.go @@ -0,0 +1,78 @@ +package mgo + +import ( + "context" + "github.com/OpenIMSDK/tools/mgoutil" + "github.com/OpenIMSDK/tools/pagination" + "github.com/OpenIMSDK/tools/utils" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/table" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewSignalInvitation(db *mongo.Database) (table.SignalInvitationInterface, error) { + coll := db.Collection("signal_invitation") + _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ + { + Keys: bson.D{ + {Key: "sid", Value: 1}, + {Key: "user_id", Value: 1}, + }, + Options: options.Index().SetUnique(true), + }, + { + Keys: bson.D{ + {Key: "initiate_time", Value: -1}, + }, + }, + }) + if err != nil { + return nil, err + } + return &signalInvitation{coll: coll}, nil +} + +type signalInvitation struct { + coll *mongo.Collection +} + +func (x *signalInvitation) Find(ctx context.Context, sid string) ([]*table.SignalInvitationModel, error) { + return mgoutil.Find[*table.SignalInvitationModel](ctx, x.coll, bson.M{"sid": sid}) +} + +func (x *signalInvitation) CreateSignalInvitation(ctx context.Context, sid string, inviteeUserIDs []string) error { + now := time.Now() + return mgoutil.InsertMany(ctx, x.coll, utils.Slice(inviteeUserIDs, func(userID string) *table.SignalInvitationModel { + return &table.SignalInvitationModel{ + UserID: userID, + SID: sid, + InitiateTime: now, + HandleTime: time.Unix(0, 0), + } + })) +} + +func (x *signalInvitation) HandleSignalInvitation(ctx context.Context, sID, InviteeUserID string, status int32) error { + return mgoutil.UpdateOne(ctx, x.coll, bson.M{"sid": sID, "user_id": InviteeUserID}, bson.M{"$set": bson.M{"status": status, "handle_time": time.Now()}}, true) +} + +func (x *signalInvitation) PageSID(ctx context.Context, recvID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []string, error) { + var and []bson.M + and = append(and, bson.M{"user_id": recvID}) + if !startTime.IsZero() { + and = append(and, bson.M{"initiate_time": bson.M{"$gte": startTime}}) + } + if !endTime.IsZero() { + and = append(and, bson.M{"initiate_time": bson.M{"$lte": endTime}}) + } + return mgoutil.FindPage[string](ctx, x.coll, bson.M{"$and": and}, pagination, options.Find().SetProjection(bson.M{"_id": 0, "sid": 1}).SetSort(bson.M{"initiate_time": -1})) +} + +func (x *signalInvitation) Delete(ctx context.Context, sids []string) error { + if len(sids) == 0 { + return nil + } + return mgoutil.DeleteMany(ctx, x.coll, bson.M{"sid": bson.M{"$in": sids}}) +} diff --git a/tools/up35/pkg/internal/rtc/mongo/table/meeting.go b/tools/up35/pkg/internal/rtc/mongo/table/meeting.go new file mode 100644 index 0000000000..3b341cfb19 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/table/meeting.go @@ -0,0 +1,51 @@ +package table + +import ( + "context" + "github.com/OpenIMSDK/tools/pagination" + "time" +) + +type MeetingInfo struct { + RoomID string `bson:"room_id"` + MeetingName string `bson:"meeting_name"` + HostUserID string `bson:"host_user_id"` + Status int64 `bson:"status"` + StartTime time.Time `bson:"start_time"` + EndTime time.Time `bson:"end_time"` + CreateTime time.Time `bson:"create_time"` + Ex string `bson:"ex"` +} + +type MeetingInterface interface { + Find(ctx context.Context, roomIDs []string) ([]*MeetingInfo, error) + CreateMeetingInfo(ctx context.Context, meetingInfo *MeetingInfo) error + UpdateMeetingInfo(ctx context.Context, roomID string, update map[string]any) error + GetUnCompleteMeetingIDList(ctx context.Context, roomIDs []string) ([]string, error) + Delete(ctx context.Context, roomIDs []string) error + GetMeetingRecords(ctx context.Context, hostUserID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []*MeetingInfo, error) +} + +type MeetingInvitationInfo struct { + RoomID string `bson:"room_id"` + UserID string `bson:"user_id"` + CreateTime time.Time `bson:"create_time"` +} + +type MeetingInvitationInterface interface { + FindUserIDs(ctx context.Context, roomID string) ([]string, error) + CreateMeetingInvitationInfo(ctx context.Context, roomID string, inviteeUserIDs []string) error + GetUserInvitedMeetingIDs(ctx context.Context, userID string) (meetingIDs []string, err error) + Delete(ctx context.Context, roomIDs []string) error + GetMeetingRecords(ctx context.Context, joinedUserID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []string, error) +} + +type MeetingVideoRecord struct { + RoomID string `bson:"room_id"` + FileURL string `bson:"file_url"` + CreateTime time.Time `bson:"create_time"` +} + +type MeetingRecordInterface interface { + CreateMeetingVideoRecord(ctx context.Context, meetingVideoRecord *MeetingVideoRecord) error +} diff --git a/tools/up35/pkg/internal/rtc/mongo/table/signal.go b/tools/up35/pkg/internal/rtc/mongo/table/signal.go new file mode 100644 index 0000000000..0cec050fff --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mongo/table/signal.go @@ -0,0 +1,73 @@ +package table + +import ( + "context" + "github.com/OpenIMSDK/tools/errs" + "github.com/OpenIMSDK/tools/pagination" + "github.com/redis/go-redis/v9" + "go.mongodb.org/mongo-driver/mongo" + "time" +) + +type SignalModel struct { + SID string `bson:"sid"` + InviterUserID string `bson:"inviter_user_id"` + CustomData string `bson:"custom_data"` + GroupID string `bson:"group_id"` + RoomID string `bson:"room_id"` + Timeout int32 `bson:"timeout"` + MediaType string `bson:"media_type"` + PlatformID int32 `bson:"platform_id"` + SessionType int32 `bson:"session_type"` + InitiateTime time.Time `bson:"initiate_time"` + EndTime time.Time `bson:"end_time"` + FileURL string `bson:"file_url"` + + Title string `bson:"title"` + Desc string `bson:"desc"` + Ex string `bson:"ex"` + IOSPushSound string `bson:"ios_push_sound"` + IOSBadgeCount bool `bson:"ios_badge_count"` + SignalInfo string `bson:"signal_info"` +} + +type SignalInterface interface { + Find(ctx context.Context, sids []string) ([]*SignalModel, error) + CreateSignal(ctx context.Context, signalModel *SignalModel) error + Update(ctx context.Context, sid string, update map[string]any) error + UpdateSignalFileURL(ctx context.Context, sID, fileURL string) error + UpdateSignalEndTime(ctx context.Context, sID string, endTime time.Time) error + Delete(ctx context.Context, sids []string) error + PageSignal(ctx context.Context, sesstionType int32, sendID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []*SignalModel, error) +} + +type SignalInvitationModel struct { + SID string `bson:"sid"` + UserID string `bson:"user_id"` + Status int32 `bson:"status"` + InitiateTime time.Time `bson:"initiate_time"` + HandleTime time.Time `bson:"handle_time"` +} + +type SignalInvitationInterface interface { + Find(ctx context.Context, sid string) ([]*SignalInvitationModel, error) + CreateSignalInvitation(ctx context.Context, sid string, inviteeUserIDs []string) error + HandleSignalInvitation(ctx context.Context, sID, InviteeUserID string, status int32) error + PageSID(ctx context.Context, recvID string, startTime, endTime time.Time, pagination pagination.Pagination) (int64, []string, error) + Delete(ctx context.Context, sids []string) error +} + +func IsNotFound(err error) bool { + if err == nil { + return false + } + err = errs.Unwrap(err) + return err == mongo.ErrNoDocuments || err == redis.Nil +} + +func IsDuplicate(err error) bool { + if err == nil { + return false + } + return mongo.IsDuplicateKeyError(errs.Unwrap(err)) +} diff --git a/tools/up35/pkg/internal/rtc/mysql/meeting.go b/tools/up35/pkg/internal/rtc/mysql/meeting.go new file mode 100644 index 0000000000..2c5bbed321 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mysql/meeting.go @@ -0,0 +1,40 @@ +package relation + +import ( + "time" +) + +type MeetingInfo struct { + RoomID string `gorm:"column:room_id;primary_key;size:128;index:room_id;index:status,priority:1"` + MeetingName string `gorm:"column:meeting_name;size:64"` + HostUserID string `gorm:"column:host_user_id;size:64;index:host_user_id"` + Status int64 `gorm:"column:status;index:status,priority:2"` + StartTime int64 `gorm:"column:start_time"` + EndTime int64 `gorm:"column:end_time"` + CreateTime time.Time `gorm:"column:create_time"` + Ex string `gorm:"column:ex;size:1024"` +} + +func (MeetingInfo) TableName() string { + return "meeting" +} + +type MeetingInvitationInfo struct { + RoomID string `gorm:"column:room_id;primary_key;size:128"` + UserID string `gorm:"column:user_id;primary_key;size:64;index:user_id"` + CreateTime time.Time `gorm:"column:create_time"` +} + +func (MeetingInvitationInfo) TableName() string { + return "meeting_invitation" +} + +type MeetingVideoRecord struct { + RoomID string `gorm:"column:room_id;size:128"` + FileURL string `gorm:"column:file_url"` + CreateTime time.Time `gorm:"column:create_time"` +} + +func (MeetingVideoRecord) TableName() string { + return "meeting_video_record" +} diff --git a/tools/up35/pkg/internal/rtc/mysql/signal.go b/tools/up35/pkg/internal/rtc/mysql/signal.go new file mode 100644 index 0000000000..3a4d607d40 --- /dev/null +++ b/tools/up35/pkg/internal/rtc/mysql/signal.go @@ -0,0 +1,43 @@ +package relation + +import ( + "time" +) + +type SignalModel struct { + SID string `gorm:"column:sid;type:char(128);primary_key"` + InviterUserID string `gorm:"column:inviter_user_id;type:char(64);index:inviter_user_id_index"` + CustomData string `gorm:"column:custom_data;type:text"` + GroupID string `gorm:"column:group_id;type:char(64)"` + RoomID string `gorm:"column:room_id;primary_key;type:char(128)"` + Timeout int32 `gorm:"column:timeout"` + MediaType string `gorm:"column:media_type;type:char(64)"` + PlatformID int32 `gorm:"column:platform_id"` + SessionType int32 `gorm:"column:sesstion_type"` + InitiateTime time.Time `gorm:"column:initiate_time"` + EndTime time.Time `gorm:"column:end_time"` + FileURL string `gorm:"column:file_url" json:"-"` + + Title string `gorm:"column:title;size:128"` + Desc string `gorm:"column:desc;size:1024"` + Ex string `gorm:"column:ex;size:1024"` + IOSPushSound string `gorm:"column:ios_push_sound"` + IOSBadgeCount bool `gorm:"column:ios_badge_count"` + SignalInfo string `gorm:"column:signal_info;size:1024"` +} + +func (SignalModel) TableName() string { + return "signal" +} + +type SignalInvitationModel struct { + UserID string `gorm:"column:user_id;primary_key"` + SID string `gorm:"column:sid;type:char(128);primary_key"` + Status int32 `gorm:"column:status"` + InitiateTime time.Time `gorm:"column:initiate_time;primary_key"` + HandleTime time.Time `gorm:"column:handle_time"` +} + +func (SignalInvitationModel) TableName() string { + return "signal_invitation" +} diff --git a/tools/up35/pkg/pkg.go b/tools/up35/pkg/pkg.go new file mode 100644 index 0000000000..d834b84922 --- /dev/null +++ b/tools/up35/pkg/pkg.go @@ -0,0 +1,206 @@ +package pkg + +import ( + "context" + "errors" + "fmt" + "gopkg.in/yaml.v3" + "log" + "os" + "reflect" + "strconv" + + "github.com/go-sql-driver/mysql" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + gormMysql "gorm.io/driver/mysql" + "gorm.io/gorm" + "gorm.io/gorm/logger" + + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" + rtcMgo "github.com/openimsdk/open-im-server/v3/tools/up35/pkg/internal/rtc/mongo/mgo" +) + +const ( + versionTable = "dataver" + versionKey = "data_version" + versionValue = 35 +) + +func InitConfig(path string) error { + data, err := os.ReadFile(path) + if err != nil { + return err + } + return yaml.Unmarshal(data, &config.Config) +} + +func GetMysql() (*gorm.DB, error) { + conf := config.Config.Mysql + mysqlDSN := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", conf.Username, conf.Password, conf.Address[0], conf.Database) + return gorm.Open(gormMysql.Open(mysqlDSN), &gorm.Config{Logger: logger.Discard}) +} + +func GetMongo() (*mongo.Database, error) { + mgo, err := unrelation.NewMongo() + if err != nil { + return nil, err + } + return mgo.GetDatabase(), nil +} + +func Main(path string) error { + if err := InitConfig(path); err != nil { + return err + } + if config.Config.Mysql == nil { + return nil + } + mongoDB, err := GetMongo() + if err != nil { + return err + } + var version struct { + Key string `bson:"key"` + Value string `bson:"value"` + } + switch mongoDB.Collection(versionTable).FindOne(context.Background(), bson.M{"key": versionKey}).Decode(&version) { + case nil: + if ver, _ := strconv.Atoi(version.Value); ver >= versionValue { + return nil + } + case mongo.ErrNoDocuments: + default: + return err + } + mysqlDB, err := GetMysql() + if err != nil { + if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1049 { + if err := SetMongoDataVersion(mongoDB, version.Value); err != nil { + return err + } + return nil // database not exist + } + return err + } + + var c convert + var tasks []func() error + tasks = append(tasks, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewUserMongo, c.User) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendMongo, c.Friend) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendRequestMongo, c.FriendRequest) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewBlackMongo, c.Black) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMongo, c.Group) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMember, c.GroupMember) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupRequestMgo, c.GroupRequest) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewConversationMongo, c.Conversation) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewS3Mongo, c.Object(config.Config.Object.Enable)) }, + func() error { return NewTask(mysqlDB, mongoDB, mgo.NewLogMongo, c.Log) }, + + func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewSignal, c.SignalModel) }, + func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewSignalInvitation, c.SignalInvitationModel) }, + func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeeting, c.Meeting) }, + func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeetingInvitation, c.MeetingInvitationInfo) }, + func() error { return NewTask(mysqlDB, mongoDB, rtcMgo.NewMeetingRecord, c.MeetingVideoRecord) }, + ) + + for _, task := range tasks { + if err := task(); err != nil { + return err + } + } + + if err := SetMongoDataVersion(mongoDB, version.Value); err != nil { + return err + } + return nil +} + +func SetMongoDataVersion(db *mongo.Database, curver string) error { + filter := bson.M{"key": versionKey, "value": curver} + update := bson.M{"$set": bson.M{"key": versionKey, "value": strconv.Itoa(versionValue)}} + _, err := db.Collection(versionTable).UpdateOne(context.Background(), filter, update, options.Update().SetUpsert(true)) + return err +} + +// NewTask A mysql table B mongodb model C mongodb table +func NewTask[A interface{ TableName() string }, B any, C any](gormDB *gorm.DB, mongoDB *mongo.Database, mongoDBInit func(db *mongo.Database) (B, error), convert func(v A) C) error { + obj, err := mongoDBInit(mongoDB) + if err != nil { + return err + } + var zero A + tableName := zero.TableName() + coll, err := getColl(obj) + if err != nil { + return fmt.Errorf("get mongo collection %s failed, err: %w", tableName, err) + } + var count int + defer func() { + log.Printf("completed convert %s total %d\n", tableName, count) + }() + const batch = 100 + for page := 0; ; page++ { + res := make([]A, 0, batch) + if err := gormDB.Limit(batch).Offset(page * batch).Find(&res).Error; err != nil { + if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1146 { + return nil // table not exist + } + return fmt.Errorf("find mysql table %s failed, err: %w", tableName, err) + } + if len(res) == 0 { + return nil + } + temp := make([]any, len(res)) + for i := range res { + temp[i] = convert(res[i]) + } + if err := insertMany(coll, temp); err != nil { + return fmt.Errorf("insert mongo table %s failed, err: %w", tableName, err) + } + count += len(res) + if len(res) < batch { + return nil + } + log.Printf("current convert %s completed %d\n", tableName, count) + } +} + +func insertMany(coll *mongo.Collection, objs []any) error { + if _, err := coll.InsertMany(context.Background(), objs); err != nil { + if !mongo.IsDuplicateKeyError(err) { + return err + } + } + for i := range objs { + _, err := coll.InsertOne(context.Background(), objs[i]) + switch { + case err == nil: + case mongo.IsDuplicateKeyError(err): + default: + return err + } + } + return nil +} + +func getColl(obj any) (_ *mongo.Collection, err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("not found %+v", e) + } + }() + stu := reflect.ValueOf(obj).Elem() + typ := reflect.TypeOf(&mongo.Collection{}).String() + for i := 0; i < stu.NumField(); i++ { + field := stu.Field(i) + if field.Type().String() == typ { + return (*mongo.Collection)(field.UnsafePointer()), nil + } + } + return nil, errors.New("not found") +} diff --git a/tools/up35/up35.go b/tools/up35/up35.go index 5d4740fca0..0ce56ee132 100644 --- a/tools/up35/up35.go +++ b/tools/up35/up35.go @@ -1,367 +1,19 @@ package main import ( - "context" - "errors" "flag" - "fmt" - "github.com/go-sql-driver/mysql" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" - mongoModel "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation" - mysqlModel "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "gopkg.in/yaml.v3" - gormMysql "gorm.io/driver/mysql" - "gorm.io/gorm" - "gorm.io/gorm/logger" + "github.com/openimsdk/open-im-server/v3/tools/up35/pkg" "log" "os" - "reflect" - "strconv" -) - -const ( - versionTable = "dataver" - versionKey = "data_version" - versionValue = 35 ) func main() { var path string flag.StringVar(&path, "c", "", "path config file") flag.Parse() - if err := Main(path); err != nil { + if err := pkg.Main(path); err != nil { log.Fatal(err) return } os.Exit(0) } - -func InitConfig(path string) error { - data, err := os.ReadFile(path) - if err != nil { - return err - } - return yaml.Unmarshal(data, &config.Config) -} - -func GetMysql() (*gorm.DB, error) { - conf := config.Config.Mysql - mysqlDSN := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", conf.Username, conf.Password, conf.Address[0], conf.Database) - return gorm.Open(gormMysql.Open(mysqlDSN), &gorm.Config{Logger: logger.Discard}) -} - -func GetMongo() (*mongo.Database, error) { - mgo, err := unrelation.NewMongo() - if err != nil { - return nil, err - } - return mgo.GetDatabase(), nil -} - -func Main(path string) error { - if err := InitConfig(path); err != nil { - return err - } - if config.Config.Mysql == nil { - return nil - } - mongoDB, err := GetMongo() - if err != nil { - return err - } - var version struct { - Key string `bson:"key"` - Value string `bson:"value"` - } - switch mongoDB.Collection(versionTable).FindOne(context.Background(), bson.M{"key": versionKey}).Decode(&version) { - case nil: - if ver, _ := strconv.Atoi(version.Value); ver >= versionValue { - return nil - } - case mongo.ErrNoDocuments: - default: - return err - } - mysqlDB, err := GetMysql() - if err != nil { - if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1049 { - if err := SetMongoDataVersion(mongoDB, version.Value); err != nil { - return err - } - return nil // database not exist - } - return err - } - - var c convert - var tasks []func() error - tasks = append(tasks, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewUserMongo, c.User) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendMongo, c.Friend) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendRequestMongo, c.FriendRequest) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewBlackMongo, c.Black) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMongo, c.Group) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMember, c.GroupMember) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupRequestMgo, c.GroupRequest) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewConversationMongo, c.Conversation) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewS3Mongo, c.Object(config.Config.Object.Enable)) }, - func() error { return NewTask(mysqlDB, mongoDB, mgo.NewLogMongo, c.Log) }, - ) - - for _, task := range tasks { - if err := task(); err != nil { - return err - } - } - - if err := SetMongoDataVersion(mongoDB, version.Value); err != nil { - return err - } - return nil -} - -func SetMongoDataVersion(db *mongo.Database, curver string) error { - filter := bson.M{"key": versionKey, "value": curver} - update := bson.M{"$set": bson.M{"key": versionKey, "value": strconv.Itoa(versionValue)}} - _, err := db.Collection(versionTable).UpdateOne(context.Background(), filter, update, options.Update().SetUpsert(true)) - return err -} - -// NewTask A mysql table B mongodb model C mongodb table -func NewTask[A interface{ TableName() string }, B any, C any](gormDB *gorm.DB, mongoDB *mongo.Database, mongoDBInit func(db *mongo.Database) (B, error), convert func(v A) C) error { - obj, err := mongoDBInit(mongoDB) - if err != nil { - return err - } - var zero A - tableName := zero.TableName() - coll, err := getColl(obj) - if err != nil { - return fmt.Errorf("get mongo collection %s failed, err: %w", tableName, err) - } - var count int - defer func() { - log.Printf("completed convert %s total %d\n", tableName, count) - }() - const batch = 100 - for page := 0; ; page++ { - res := make([]A, 0, batch) - if err := gormDB.Limit(batch).Offset(page * batch).Find(&res).Error; err != nil { - if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1146 { - return nil // table not exist - } - return fmt.Errorf("find mysql table %s failed, err: %w", tableName, err) - } - if len(res) == 0 { - return nil - } - temp := make([]any, len(res)) - for i := range res { - temp[i] = convert(res[i]) - } - if err := insertMany(coll, temp); err != nil { - return fmt.Errorf("insert mongo table %s failed, err: %w", tableName, err) - } - count += len(res) - if len(res) < batch { - return nil - } - log.Printf("current convert %s completed %d\n", tableName, count) - } -} - -func insertMany(coll *mongo.Collection, objs []any) error { - if _, err := coll.InsertMany(context.Background(), objs); err != nil { - if !mongo.IsDuplicateKeyError(err) { - return err - } - } - for i := range objs { - _, err := coll.InsertOne(context.Background(), objs[i]) - switch { - case err == nil: - case mongo.IsDuplicateKeyError(err): - default: - return err - } - } - return nil -} - -func getColl(obj any) (_ *mongo.Collection, err error) { - defer func() { - if e := recover(); e != nil { - err = fmt.Errorf("not found %+v", e) - } - }() - stu := reflect.ValueOf(obj).Elem() - typ := reflect.TypeOf(&mongo.Collection{}).String() - for i := 0; i < stu.NumField(); i++ { - field := stu.Field(i) - if field.Type().String() == typ { - return (*mongo.Collection)(field.UnsafePointer()), nil - } - } - return nil, errors.New("not found") -} - -type convert struct{} - -func (convert) User(v mysqlModel.UserModel) mongoModel.UserModel { - return mongoModel.UserModel{ - UserID: v.UserID, - Nickname: v.Nickname, - FaceURL: v.FaceURL, - Ex: v.Ex, - AppMangerLevel: v.AppMangerLevel, - GlobalRecvMsgOpt: v.GlobalRecvMsgOpt, - CreateTime: v.CreateTime, - } -} - -func (convert) Friend(v mysqlModel.FriendModel) mongoModel.FriendModel { - return mongoModel.FriendModel{ - OwnerUserID: v.OwnerUserID, - FriendUserID: v.FriendUserID, - Remark: v.Remark, - CreateTime: v.CreateTime, - AddSource: v.AddSource, - OperatorUserID: v.OperatorUserID, - Ex: v.Ex, - } -} - -func (convert) FriendRequest(v mysqlModel.FriendRequestModel) mongoModel.FriendRequestModel { - return mongoModel.FriendRequestModel{ - FromUserID: v.FromUserID, - ToUserID: v.ToUserID, - HandleResult: v.HandleResult, - ReqMsg: v.ReqMsg, - CreateTime: v.CreateTime, - HandlerUserID: v.HandlerUserID, - HandleMsg: v.HandleMsg, - HandleTime: v.HandleTime, - Ex: v.Ex, - } -} - -func (convert) Black(v mysqlModel.BlackModel) mongoModel.BlackModel { - return mongoModel.BlackModel{ - OwnerUserID: v.OwnerUserID, - BlockUserID: v.BlockUserID, - CreateTime: v.CreateTime, - AddSource: v.AddSource, - OperatorUserID: v.OperatorUserID, - Ex: v.Ex, - } -} - -func (convert) Group(v mysqlModel.GroupModel) mongoModel.GroupModel { - return mongoModel.GroupModel{ - GroupID: v.GroupID, - GroupName: v.GroupName, - Notification: v.Notification, - Introduction: v.Introduction, - FaceURL: v.FaceURL, - CreateTime: v.CreateTime, - Ex: v.Ex, - Status: v.Status, - CreatorUserID: v.CreatorUserID, - GroupType: v.GroupType, - NeedVerification: v.NeedVerification, - LookMemberInfo: v.LookMemberInfo, - ApplyMemberFriend: v.ApplyMemberFriend, - NotificationUpdateTime: v.NotificationUpdateTime, - NotificationUserID: v.NotificationUserID, - } -} - -func (convert) GroupMember(v mysqlModel.GroupMemberModel) mongoModel.GroupMemberModel { - return mongoModel.GroupMemberModel{ - GroupID: v.GroupID, - UserID: v.UserID, - Nickname: v.Nickname, - FaceURL: v.FaceURL, - RoleLevel: v.RoleLevel, - JoinTime: v.JoinTime, - JoinSource: v.JoinSource, - InviterUserID: v.InviterUserID, - OperatorUserID: v.OperatorUserID, - MuteEndTime: v.MuteEndTime, - Ex: v.Ex, - } -} - -func (convert) GroupRequest(v mysqlModel.GroupRequestModel) mongoModel.GroupRequestModel { - return mongoModel.GroupRequestModel{ - UserID: v.UserID, - GroupID: v.GroupID, - HandleResult: v.HandleResult, - ReqMsg: v.ReqMsg, - HandledMsg: v.HandledMsg, - ReqTime: v.ReqTime, - HandleUserID: v.HandleUserID, - HandledTime: v.HandledTime, - JoinSource: v.JoinSource, - InviterUserID: v.InviterUserID, - Ex: v.Ex, - } -} - -func (convert) Conversation(v mysqlModel.ConversationModel) mongoModel.ConversationModel { - return mongoModel.ConversationModel{ - OwnerUserID: v.OwnerUserID, - ConversationID: v.ConversationID, - ConversationType: v.ConversationType, - UserID: v.UserID, - GroupID: v.GroupID, - RecvMsgOpt: v.RecvMsgOpt, - IsPinned: v.IsPinned, - IsPrivateChat: v.IsPrivateChat, - BurnDuration: v.BurnDuration, - GroupAtType: v.GroupAtType, - AttachedInfo: v.AttachedInfo, - Ex: v.Ex, - MaxSeq: v.MaxSeq, - MinSeq: v.MinSeq, - CreateTime: v.CreateTime, - IsMsgDestruct: v.IsMsgDestruct, - MsgDestructTime: v.MsgDestructTime, - LatestMsgDestructTime: v.LatestMsgDestructTime, - } -} - -func (convert) Object(engine string) func(v mysqlModel.ObjectModel) mongoModel.ObjectModel { - return func(v mysqlModel.ObjectModel) mongoModel.ObjectModel { - return mongoModel.ObjectModel{ - Name: v.Name, - UserID: v.UserID, - Hash: v.Hash, - Engine: engine, - Key: v.Key, - Size: v.Size, - ContentType: v.ContentType, - Group: v.Cause, - CreateTime: v.CreateTime, - } - } -} - -func (convert) Log(v mysqlModel.Log) mongoModel.LogModel { - return mongoModel.LogModel{ - LogID: v.LogID, - Platform: v.Platform, - UserID: v.UserID, - CreateTime: v.CreateTime, - Url: v.Url, - FileName: v.FileName, - SystemType: v.SystemType, - Version: v.Version, - Ex: v.Ex, - } -} From 98669f176638604ed192d92c440b8e300b3a6d4d Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 11 Dec 2023 15:27:20 +0800 Subject: [PATCH 02/14] upgrade package and rtc convert --- internal/rpc/friend/friend.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 7f22c9d0d1..1cea29d6ab 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -16,6 +16,7 @@ package friend import ( "context" + "errors" "github.com/OpenIMSDK/tools/tx" @@ -53,6 +54,10 @@ type friendServer struct { RegisterCenter registry.SvcDiscoveryRegistry } +func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) { + return nil, errors.New("implement me") +} + func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { // Initialize MongoDB mongo, err := unrelation.NewMongo() From cb47410f4b41df76d076f6068b75a21eb95c8a2b Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 11 Dec 2023 15:31:48 +0800 Subject: [PATCH 03/14] upgrade package and rtc convert --- go.mod | 2 +- go.sum | 4 ++-- internal/rpc/friend/friend.go | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index ec547aa625..11d374d084 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( firebase.google.com/go v3.13.0+incompatible - github.com/OpenIMSDK/protocol v0.0.33 + github.com/OpenIMSDK/protocol v0.0.31 github.com/OpenIMSDK/tools v0.0.20 github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/dtm-labs/rockscache v0.1.1 diff --git a/go.sum b/go.sum index 71565c8693..30e4b3cb4d 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= -github.com/OpenIMSDK/protocol v0.0.33 h1:T07KWD0jt7IRlrYRujCa+eXmfgcSi8sRgLL8t2ZlHQA= -github.com/OpenIMSDK/protocol v0.0.33/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= +github.com/OpenIMSDK/protocol v0.0.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE= +github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k= github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 1cea29d6ab..224efe3ed5 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -16,8 +16,6 @@ package friend import ( "context" - "errors" - "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/protocol/sdkws" @@ -54,10 +52,6 @@ type friendServer struct { RegisterCenter registry.SvcDiscoveryRegistry } -func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) { - return nil, errors.New("implement me") -} - func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { // Initialize MongoDB mongo, err := unrelation.NewMongo() From 24e836c434fed567ea2891b524519b609941a281 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 12 Dec 2023 18:10:11 +0800 Subject: [PATCH 04/14] upgrade package and rtc convert --- tools/data-conversion/go.mod | 28 ++++++++-------- tools/data-conversion/go.sum | 65 +++++++++++++++++------------------- tools/up35/go.mod | 48 -------------------------- 3 files changed, 45 insertions(+), 96 deletions(-) diff --git a/tools/data-conversion/go.mod b/tools/data-conversion/go.mod index b0d7aea13e..37d1776c2c 100644 --- a/tools/data-conversion/go.mod +++ b/tools/data-conversion/go.mod @@ -3,16 +3,16 @@ module github.com/openimsdk/open-im-server/v3/tools/data-conversion go 1.19 require ( - github.com/IBM/sarama v1.41.2 - github.com/OpenIMSDK/protocol v0.0.23 - github.com/OpenIMSDK/tools v0.0.14 + github.com/IBM/sarama v1.42.1 + github.com/OpenIMSDK/protocol v0.0.33 + github.com/OpenIMSDK/tools v0.0.20 github.com/golang/protobuf v1.5.3 - github.com/openimsdk/open-im-server/v3 v3.3.2 - golang.org/x/net v0.17.0 - google.golang.org/grpc v1.57.0 + github.com/openimsdk/open-im-server/v3 v3.4.0 + golang.org/x/net v0.19.0 + google.golang.org/grpc v1.60.0 google.golang.org/protobuf v1.31.0 - gorm.io/driver/mysql v1.5.1 - gorm.io/gorm v1.25.4 + gorm.io/driver/mysql v1.5.2 + gorm.io/gorm v1.25.5 ) require ( @@ -28,7 +28,7 @@ require ( github.com/gin-gonic/gin v1.9.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.15.3 // indirect + github.com/go-playground/validator/v10 v10.15.5 // indirect github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang/snappy v0.0.4 // indirect @@ -63,10 +63,10 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.24.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/image v0.12.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect + golang.org/x/crypto v0.16.0 // indirect + golang.org/x/image v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/tools/data-conversion/go.sum b/tools/data-conversion/go.sum index 9223f6e363..66f85785b7 100644 --- a/tools/data-conversion/go.sum +++ b/tools/data-conversion/go.sum @@ -1,9 +1,9 @@ -github.com/IBM/sarama v1.41.2 h1:ZDBZfGPHAD4uuAtSv4U22fRZBgst0eEwGFzLj0fb85c= -github.com/IBM/sarama v1.41.2/go.mod h1:xdpu7sd6OE1uxNdjYTSKUfY8FaKkJES9/+EyjSgiGQk= -github.com/OpenIMSDK/protocol v0.0.23 h1:L545aRQez6Ro+AaJB1Z6Mz7ojnDtp41WqASxYveCkcE= -github.com/OpenIMSDK/protocol v0.0.23/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= -github.com/OpenIMSDK/tools v0.0.14 h1:WLof/+WxyPyRST+QkoTKubYCiV73uCLiL8pgnpH/yKQ= -github.com/OpenIMSDK/tools v0.0.14/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= +github.com/IBM/sarama v1.42.1 h1:wugyWa15TDEHh2kvq2gAy1IHLjEjuYOYgXz/ruC/OSQ= +github.com/IBM/sarama v1.42.1/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= +github.com/OpenIMSDK/protocol v0.0.33 h1:T07KWD0jt7IRlrYRujCa+eXmfgcSi8sRgLL8t2ZlHQA= +github.com/OpenIMSDK/protocol v0.0.33/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= +github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k= +github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= @@ -34,8 +34,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo= -github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -47,7 +47,7 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= @@ -103,8 +103,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/openimsdk/open-im-server/v3 v3.3.2 h1:uK6glaidrnWlYXFSwzOEq7fXS6jT1OyesUJENZJeptI= -github.com/openimsdk/open-im-server/v3 v3.3.2/go.mod h1:rqKiCkjav5P7tQmyqaixnMJcayWlM4XtXmwG+cZNw78= +github.com/openimsdk/open-im-server/v3 v3.4.0 h1:e7nslaWEHYc5xD1A3zHtnhbIWgfgtJSnPGHIqwjARaE= +github.com/openimsdk/open-im-server/v3 v3.4.0/go.mod h1:HKqjLZSMjD7ec59VV694Yfqnj9SIVotzDSPWgAei2Tg= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= @@ -146,24 +146,22 @@ golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= -golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= +golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -171,8 +169,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -180,18 +178,17 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 h1:wukfNtZmZUurLN/atp2hiIeTKn7QJWIQdHzqmsOnAOk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= +google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= @@ -202,9 +199,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= -gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= -gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= -gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs= +gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= +gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= +gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/tools/up35/go.mod b/tools/up35/go.mod index 5ae3907bff..23163a4dcd 100644 --- a/tools/up35/go.mod +++ b/tools/up35/go.mod @@ -1,51 +1,3 @@ module github.com/openimsdk/open-im-server/v3/tools/up35 go 1.19 - -require ( - github.com/go-sql-driver/mysql v1.7.1 - github.com/openimsdk/open-im-server/v3 v3.5.0 - github.com/openimsdk/open-im-server/v3/tools/data-conversion v0.0.0-00010101000000-000000000000 - go.mongodb.org/mongo-driver v1.12.1 - gopkg.in/yaml.v3 v3.0.1 - gorm.io/driver/mysql v1.5.1 - gorm.io/gorm v1.25.4 -) - -require ( - github.com/OpenIMSDK/protocol v0.0.31 // indirect - github.com/OpenIMSDK/tools v0.0.18 // indirect - github.com/bwmarrin/snowflake v0.3.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/jinzhu/copier v0.4.0 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect - github.com/lestrrat-go/strftime v1.0.6 // indirect - github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect - github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.2 // indirect - github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - go.uber.org/atomic v1.7.0 // indirect - go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/image v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect -) - -replace ( - github.com/openimsdk/open-im-server/v3 => ./../../../open-im-server - github.com/openimsdk/open-im-server/v3/tools/data-conversion => ./../data-conversion -) From 9d439521793c98bbad393feb5020d24ace78b509 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 12 Dec 2023 18:15:49 +0800 Subject: [PATCH 05/14] friend user --- internal/rpc/friend/friend.go | 4 ++++ internal/rpc/user/user.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 224efe3ed5..21422fae30 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -52,6 +52,10 @@ type friendServer struct { RegisterCenter registry.SvcDiscoveryRegistry } +func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { // Initialize MongoDB mongo, err := unrelation.NewMongo() diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index 77da408aa7..a2fa14c7a4 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -56,6 +56,22 @@ type userServer struct { RegisterCenter registry.SvcDiscoveryRegistry } +func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + +func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + +func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + +func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { rdb, err := cache.NewRedis() if err != nil { From 00f0d9fb424cd5b95b7396703a2ac64e1e562cac Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Fri, 15 Dec 2023 19:07:21 +0800 Subject: [PATCH 06/14] s3 form data --- go.mod | 4 +- go.sum | 2 - internal/api/route.go | 2 + internal/api/third.go | 8 ++ internal/rpc/third/s3.go | 112 ++++++++++++++++++++++ internal/rpc/third/tool.go | 3 + pkg/common/cmd/root.go | 2 +- pkg/common/db/controller/s3.go | 10 ++ pkg/common/db/s3/cont/consts.go | 1 + pkg/common/db/s3/cont/controller.go | 4 + pkg/common/db/s3/cos/cos.go | 4 + pkg/common/db/s3/minio/minio.go | 36 +++++++ pkg/common/db/s3/minio/minio_test.go | 37 +++++++ pkg/common/db/s3/oss/oss.go | 4 + pkg/common/db/s3/s3.go | 10 ++ pkg/common/ginprometheus/ginprometheus.go | 2 +- 16 files changed, 236 insertions(+), 5 deletions(-) create mode 100644 pkg/common/db/s3/minio/minio_test.go diff --git a/go.mod b/go.mod index 11d374d084..4a0520e670 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( firebase.google.com/go v3.13.0+incompatible - github.com/OpenIMSDK/protocol v0.0.31 + github.com/OpenIMSDK/protocol v0.0.35 github.com/OpenIMSDK/tools v0.0.20 github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/dtm-labs/rockscache v0.1.1 @@ -154,3 +154,5 @@ require ( golang.org/x/crypto v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) + +replace github.com/OpenIMSDK/protocol => C:\Users\openIM\Desktop\fork\protocol diff --git a/go.sum b/go.sum index 30e4b3cb4d..9684c10795 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= -github.com/OpenIMSDK/protocol v0.0.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE= -github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k= github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= diff --git a/internal/api/route.go b/internal/api/route.go index 7a331d643d..0b8be95fd5 100644 --- a/internal/api/route.go +++ b/internal/api/route.go @@ -161,6 +161,8 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive objectGroup.POST("/auth_sign", t.AuthSign) objectGroup.POST("/complete_multipart_upload", t.CompleteMultipartUpload) objectGroup.POST("/access_url", t.AccessURL) + objectGroup.POST("/initiate_form_data", t.InitiateFormData) + objectGroup.POST("/complete_form_data", t.CompleteFormData) objectGroup.GET("/*name", t.ObjectRedirect) } // Message diff --git a/internal/api/third.go b/internal/api/third.go index 5191903da7..37ec55098c 100644 --- a/internal/api/third.go +++ b/internal/api/third.go @@ -71,6 +71,14 @@ func (o *ThirdApi) AccessURL(c *gin.Context) { a2r.Call(third.ThirdClient.AccessURL, o.Client, c) } +func (o *ThirdApi) InitiateFormData(c *gin.Context) { + a2r.Call(third.ThirdClient.InitiateFormData, o.Client, c) +} + +func (o *ThirdApi) CompleteFormData(c *gin.Context) { + a2r.Call(third.ThirdClient.CompleteFormData, o.Client, c) +} + func (o *ThirdApi) ObjectRedirect(c *gin.Context) { name := c.Param("name") if name == "" { diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index ca826e8058..14d1d51767 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -16,6 +16,12 @@ package third import ( "context" + "encoding/base64" + "encoding/hex" + "encoding/json" + "github.com/google/uuid" + "github.com/openimsdk/open-im-server/v3/pkg/authverify" + "path" "strconv" "time" @@ -179,6 +185,112 @@ func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (* }, nil } +const direct = "direct" + +func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateFormDataReq) (*third.InitiateFormDataResp, error) { + if req.Name == "" { + return nil, errs.ErrArgs.Wrap("name is empty") + } + if req.Size <= 0 { + return nil, errs.ErrArgs.Wrap("size must be greater than 0") + } + if err := checkUploadName(ctx, req.Name); err != nil { + return nil, err + } + var duration time.Duration + opUserID := mcontext.GetOpUserID(ctx) + var key string + if authverify.IsManagerUserID(opUserID) { + if req.Millisecond <= 0 { + duration = time.Minute * 10 + } else { + duration = time.Millisecond * time.Duration(req.Millisecond) + } + if req.Absolute { + key = req.Name + } + } else { + duration = time.Minute * 10 + } + uid, err := uuid.NewRandom() + if err != nil { + return nil, err + } + if key == "" { + date := time.Now().Format("20060102") + key = path.Join(cont.DirectPath, date, opUserID, hex.EncodeToString(uid[:])+path.Ext(req.Name)) + } + mate := FormDataMate{ + Name: req.Name, + Size: req.Size, + ContentType: req.ContentType, + Group: req.Group, + Key: key, + } + mateData, err := json.Marshal(&mate) + if err != nil { + return nil, err + } + resp, err := t.s3dataBase.FormData(ctx, key, req.Size, req.ContentType, duration) + if err != nil { + return nil, err + } + return &third.InitiateFormDataResp{ + Id: base64.RawStdEncoding.EncodeToString(mateData), + Url: resp.URL, + File: resp.File, + Header: toPbMapArray(resp.Header), + FormData: resp.FormData, + Expires: resp.Expires.UnixMilli(), + }, nil +} + +func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.CompleteFormDataReq) (*third.CompleteFormDataResp, error) { + if req.Id == "" { + return nil, errs.ErrArgs.Wrap("id is empty") + } + data, err := base64.RawStdEncoding.DecodeString(req.Id) + if err != nil { + return nil, errs.ErrArgs.Wrap("invalid id " + err.Error()) + } + var mate FormDataMate + if err := json.Unmarshal(data, &mate); err != nil { + return nil, errs.ErrArgs.Wrap("invalid id " + err.Error()) + } + if err := checkUploadName(ctx, mate.Name); err != nil { + return nil, err + } + info, err := t.s3dataBase.StatObject(ctx, mate.Key) + if err != nil { + return nil, err + } + if info.Size > 0 && info.Size != mate.Size { + return nil, errs.ErrData.Wrap("file size mismatch") + } + obj := &relation.ObjectModel{ + Name: mate.Name, + UserID: mcontext.GetOpUserID(ctx), + Hash: "etag_" + info.ETag, + Key: info.Key, + Size: info.Size, + ContentType: mate.ContentType, + Group: mate.Group, + CreateTime: time.Now(), + } + if err := t.s3dataBase.SetObject(ctx, obj); err != nil { + return nil, err + } + return &third.CompleteFormDataResp{Url: t.apiAddress(mate.Name)}, nil +} + func (t *thirdServer) apiAddress(name string) string { return t.apiURL + name } + +type FormDataMate struct { + Name string `json:"name"` + Size int64 `json:"size"` + ContentType string `json:"contentType"` + Group string `json:"group"` + Key string `json:"key"` +} diff --git a/internal/rpc/third/tool.go b/internal/rpc/third/tool.go index a65d882dd5..a6c16ff9d1 100644 --- a/internal/rpc/third/tool.go +++ b/internal/rpc/third/tool.go @@ -29,6 +29,9 @@ import ( ) func toPbMapArray(m map[string][]string) []*third.KeyValues { + if len(m) == 0 { + return nil + } res := make([]*third.KeyValues, 0, len(m)) for key := range m { res = append(res, &third.KeyValues{ diff --git a/pkg/common/cmd/root.go b/pkg/common/cmd/root.go index 0bc308e072..66bec61a79 100644 --- a/pkg/common/cmd/root.go +++ b/pkg/common/cmd/root.go @@ -45,7 +45,7 @@ type CmdOpts struct { func WithCronTaskLogName() func(*CmdOpts) { return func(opts *CmdOpts) { - opts.loggerPrefixName = "OpenIM.CronTask.log.all" + opts.loggerPrefixName = "openim.crontask.log.all" } } diff --git a/pkg/common/db/controller/s3.go b/pkg/common/db/controller/s3.go index 6916a7d30d..95505de417 100644 --- a/pkg/common/db/controller/s3.go +++ b/pkg/common/db/controller/s3.go @@ -35,6 +35,8 @@ type S3Database interface { CompleteMultipartUpload(ctx context.Context, uploadID string, parts []string) (*cont.UploadResult, error) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) SetObject(ctx context.Context, info *relation.ObjectModel) error + StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) + FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) } func NewS3Database(rdb redis.UniversalClient, s3 s3.Interface, obj relation.ObjectInfoModelInterface) S3Database { @@ -100,3 +102,11 @@ func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Dur } return expireTime, rawURL, nil } + +func (s *s3Database) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) { + return s.s3.StatObject(ctx, name) +} + +func (s *s3Database) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { + return s.s3.FormData(ctx, name, size, contentType, duration) +} diff --git a/pkg/common/db/s3/cont/consts.go b/pkg/common/db/s3/cont/consts.go index 1a0467ce57..a01a8312c0 100644 --- a/pkg/common/db/s3/cont/consts.go +++ b/pkg/common/db/s3/cont/consts.go @@ -17,6 +17,7 @@ package cont const ( hashPath = "openim/data/hash/" tempPath = "openim/temp/" + DirectPath = "openim/direct" UploadTypeMultipart = 1 // 分片上传 UploadTypePresigned = 2 // 预签名上传 partSeparator = "," diff --git a/pkg/common/db/s3/cont/controller.go b/pkg/common/db/s3/cont/controller.go index 1bf1a4b12c..82c27c1f21 100644 --- a/pkg/common/db/s3/cont/controller.go +++ b/pkg/common/db/s3/cont/controller.go @@ -279,3 +279,7 @@ func (c *Controller) AccessURL(ctx context.Context, name string, expire time.Dur } return c.impl.AccessURL(ctx, name, expire, opt) } + +func (c *Controller) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { + return c.impl.FormData(ctx, name, size, contentType, duration) +} diff --git a/pkg/common/db/s3/cos/cos.go b/pkg/common/db/s3/cos/cos.go index 7add88487f..ca8eb16940 100644 --- a/pkg/common/db/s3/cos/cos.go +++ b/pkg/common/db/s3/cos/cos.go @@ -326,3 +326,7 @@ func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Dura } return c.client.Object.GetObjectURL(name), nil } + +func (c *Cos) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { + return nil, errors.New("cos temporarily not supported") +} diff --git a/pkg/common/db/s3/minio/minio.go b/pkg/common/db/s3/minio/minio.go index be49e2faa3..914e2ae540 100644 --- a/pkg/common/db/s3/minio/minio.go +++ b/pkg/common/db/s3/minio/minio.go @@ -441,3 +441,39 @@ func (m *Minio) getObjectData(ctx context.Context, name string, limit int64) ([] } return io.ReadAll(io.LimitReader(object, limit)) } + +func (m *Minio) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { + if err := m.initMinio(ctx); err != nil { + return nil, err + } + policy := minio.NewPostPolicy() + if err := policy.SetKey(name); err != nil { + return nil, err + } + expires := time.Now().Add(duration) + if err := policy.SetExpires(expires); err != nil { + return nil, err + } + if err := policy.SetContentLengthRange(0, size); err != nil { + return nil, err + } + if contentType != "" { + if err := policy.SetContentType(contentType); err != nil { + return nil, err + } + } + if err := policy.SetBucket(config.Config.Object.Minio.Bucket); err != nil { + return nil, err + } + u, fd, err := m.core.PresignedPostPolicy(ctx, policy) + if err != nil { + panic(err) + } + return &s3.FormData{ + URL: u.String(), + File: "file", + Header: nil, + FormData: fd, + Expires: expires, + }, nil +} diff --git a/pkg/common/db/s3/minio/minio_test.go b/pkg/common/db/s3/minio/minio_test.go new file mode 100644 index 0000000000..2c721eb256 --- /dev/null +++ b/pkg/common/db/s3/minio/minio_test.go @@ -0,0 +1,37 @@ +package minio + +import ( + "context" + "github.com/minio/minio-go/v7" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "testing" + "time" +) + +func TestName(t *testing.T) { + config.Config.Object.Minio.Bucket = "openim" + config.Config.Object.Minio.AccessKeyID = "root" + config.Config.Object.Minio.SecretAccessKey = "openIM123" + config.Config.Object.Minio.Endpoint = "http://172.16.8.38:10005" + tmp, err := NewMinio(nil) + if err != nil { + panic(err) + } + min := tmp.(*Minio) + cli := min.core.Client + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + policy := minio.NewPostPolicy() + _ = policy.SetExpires(time.Now().Add(time.Hour)) + _ = policy.SetKey("test.txt") + _ = policy.SetBucket(config.Config.Object.Minio.Bucket) + policy.SetContentType("text/plain") + u, fd, err := cli.PresignedPostPolicy(ctx, policy) + if err != nil { + panic(err) + } + t.Log(u) + for k, v := range fd { + t.Log(k, v) + } +} diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go index 6a728127bb..a4c34fa826 100644 --- a/pkg/common/db/s3/oss/oss.go +++ b/pkg/common/db/s3/oss/oss.go @@ -327,3 +327,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, params := getURLParams(*o.bucket.Client.Conn, rawParams) return getURL(o.um, o.bucket.BucketName, name, params).String(), nil } + +func (o *OSS) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { + return nil, errors.New("oss temporarily not supported") +} diff --git a/pkg/common/db/s3/s3.go b/pkg/common/db/s3/s3.go index afbe919551..3ca29943b3 100644 --- a/pkg/common/db/s3/s3.go +++ b/pkg/common/db/s3/s3.go @@ -74,6 +74,14 @@ type CopyObjectInfo struct { ETag string `json:"etag"` } +type FormData struct { + URL string `json:"url"` + File string `json:"file"` + Header http.Header `json:"header"` + FormData map[string]string `json:"form"` + Expires time.Time `json:"expires"` +} + type SignPart struct { PartNumber int `json:"partNumber"` URL string `json:"url"` @@ -152,4 +160,6 @@ type Interface interface { ListUploadedParts(ctx context.Context, uploadID string, name string, partNumberMarker int, maxParts int) (*ListUploadedPartsResult, error) AccessURL(ctx context.Context, name string, expire time.Duration, opt *AccessURLOption) (string, error) + + FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*FormData, error) } diff --git a/pkg/common/ginprometheus/ginprometheus.go b/pkg/common/ginprometheus/ginprometheus.go index a325595d60..132e97770e 100644 --- a/pkg/common/ginprometheus/ginprometheus.go +++ b/pkg/common/ginprometheus/ginprometheus.go @@ -418,7 +418,7 @@ func computeApproximateRequestSize(r *http.Request) int { } s += len(r.Host) - // r.Form and r.MultipartForm are assumed to be included in r.URL. + // r.FormData and r.MultipartForm are assumed to be included in r.URL. if r.ContentLength != -1 { s += int(r.ContentLength) From 67a4af8d5c20528d7260bf7e9f7778e1605ef301 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Mon, 25 Dec 2023 18:36:14 +0800 Subject: [PATCH 07/14] s3 form data --- go.mod | 4 +- go.sum | 10 ++++ pkg/common/db/s3/cos/cos.go | 84 +++++++++++++++++++++++++++- pkg/common/db/s3/minio/minio.go | 20 ++++--- pkg/common/db/s3/minio/minio_test.go | 66 ++++++++++++++++++---- pkg/common/db/s3/oss/oss.go | 41 +++++++++++++- pkg/common/db/s3/s3.go | 11 ++-- 7 files changed, 208 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 4a0520e670..8e8b425a45 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require github.com/google/uuid v1.3.1 require ( github.com/IBM/sarama v1.41.3 - github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible + github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible github.com/go-redis/redis v6.15.9+incompatible github.com/redis/go-redis/v9 v9.2.1 github.com/tencentyun/cos-go-sdk-v5 v0.7.45 @@ -132,7 +132,7 @@ require ( golang.org/x/oauth2 v0.13.0 // indirect golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect diff --git a/go.sum b/go.sum index 9684c10795..6faa5d97c0 100644 --- a/go.sum +++ b/go.sum @@ -25,6 +25,8 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBb github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= +github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible h1:so4m5rRA32Tc5GgKg/5gKUu0CRsYmVO3ThMP6T3CwLc= +github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -89,6 +91,7 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -196,8 +199,10 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -250,6 +255,7 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w= github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -378,6 +384,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -451,6 +458,8 @@ golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -462,6 +471,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/common/db/s3/cos/cos.go b/pkg/common/db/s3/cos/cos.go index ca8eb16940..15d7c57d39 100644 --- a/pkg/common/db/s3/cos/cos.go +++ b/pkg/common/db/s3/cos/cos.go @@ -16,8 +16,14 @@ package cos import ( "context" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/hex" + "encoding/json" "errors" "fmt" + "io" "net/http" "net/url" "strconv" @@ -44,6 +50,8 @@ const ( imageWebp = "webp" ) +const successCode = http.StatusOK + const ( videoSnapshotImagePng = "png" videoSnapshotImageJpg = "jpg" @@ -328,5 +336,79 @@ func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Dura } func (c *Cos) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { - return nil, errors.New("cos temporarily not supported") + //res, _, err := c.client.Object.ListUploads(ctx, &cos.ObjectListUploadsOptions{}) + //if err != nil { + // return nil, err + //} + now := time.Now() + expiration := now.Add(duration) + keyTime := fmt.Sprintf("%d;%d", now.Unix(), expiration.Unix()) + conditions := []any{ + map[string]string{"success_action_status": strconv.Itoa(successCode)}, + []any{"content-length-range", 0, size}, + map[string]string{"q-sign-time": keyTime}, + map[string]string{"key": name}, + map[string]string{"q-sign-algorithm": "sha1"}, + } + if c.credential.SessionToken != "" { + conditions = append(conditions, map[string]string{"x-cos-security-token": c.credential.SessionToken}) + } + policy := map[string]any{ + "expiration": expiration.Format("2006-01-02T15:04:05.000Z"), + "conditions": []any{ + //map[string]string{"bucket": res.Bucket}, + //map[string]string{"acl": "default"}, + map[string]string{"q-sign-algorithm": "sha1"}, + map[string]string{"q-ak": c.credential.SecretID}, + map[string]string{"q-sign-time": keyTime}, + + //map[string]string{"success_action_status": strconv.Itoa(successCode)}, + //[]any{"content-length-range", 0, size}, + //map[string]string{"key": name}, + //map[string]string{"x-cos-security-token": c.credential.SessionToken}, + }, + } + policyJson, err := json.Marshal(policy) + if err != nil { + return nil, err + } + //signKey := hmacSha1val(c.credential.SecretKey, keyTime) + //policyStr := hmacSha1val(sha1val(signKey), string(policyJson)) + + policyStr := base64.StdEncoding.EncodeToString(policyJson) + h := hmac.New(sha1.New, []byte(c.credential.SecretKey)) + if _, err := io.WriteString(h, policyStr); err != nil { + return nil, err + } + fd := &s3.FormData{ + URL: c.client.BaseURL.BucketURL.String(), + File: "file", + Expires: expiration, + FormData: map[string]string{ + "key": name, + "policy": policyStr, + "q-sign-algorithm": "sha1", + "q-ak": c.credential.SecretID, + "q-key-time": keyTime, + "q-signature": hex.EncodeToString(h.Sum(nil)), + }, + SuccessCodes: []int{successCode}, + } + if c.credential.SessionToken != "" { + fd.FormData["x-cos-security-token"] = c.credential.SessionToken + } + // 2019-08-30 17:38:12 + return fd, nil +} + +func hmacSha1val(key, msg string) string { + v := hmac.New(sha1.New, []byte(key)) + v.Write([]byte(msg)) + return hex.EncodeToString(v.Sum(nil)) +} + +func sha1val(msg string) string { + sha1Hash := sha1.New() + sha1Hash.Write([]byte(msg)) + return hex.EncodeToString(sha1Hash.Sum(nil)) } diff --git a/pkg/common/db/s3/minio/minio.go b/pkg/common/db/s3/minio/minio.go index 914e2ae540..4300520580 100644 --- a/pkg/common/db/s3/minio/minio.go +++ b/pkg/common/db/s3/minio/minio.go @@ -57,6 +57,8 @@ const ( imageThumbnailPath = "openim/thumbnail" ) +const successCode = http.StatusOK + func NewMinio(cache cache.MinioCache) (s3.Interface, error) { u, err := url.Parse(config.Config.Object.Minio.Endpoint) if err != nil { @@ -457,23 +459,27 @@ func (m *Minio) FormData(ctx context.Context, name string, size int64, contentTy if err := policy.SetContentLengthRange(0, size); err != nil { return nil, err } + if err := policy.SetSuccessStatusAction(strconv.Itoa(successCode)); err != nil { + return nil, err + } if contentType != "" { if err := policy.SetContentType(contentType); err != nil { return nil, err } } - if err := policy.SetBucket(config.Config.Object.Minio.Bucket); err != nil { + if err := policy.SetBucket(m.bucket); err != nil { return nil, err } u, fd, err := m.core.PresignedPostPolicy(ctx, policy) if err != nil { - panic(err) + return nil, err } return &s3.FormData{ - URL: u.String(), - File: "file", - Header: nil, - FormData: fd, - Expires: expires, + URL: u.String(), + File: "file", + Header: nil, + FormData: fd, + Expires: expires, + SuccessCodes: []int{successCode}, }, nil } diff --git a/pkg/common/db/s3/minio/minio_test.go b/pkg/common/db/s3/minio/minio_test.go index 2c721eb256..0780c40212 100644 --- a/pkg/common/db/s3/minio/minio_test.go +++ b/pkg/common/db/s3/minio/minio_test.go @@ -1,9 +1,15 @@ package minio import ( + "bytes" "context" - "github.com/minio/minio-go/v7" + "errors" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" + "io" + "mime/multipart" + "net/http" + "path" "testing" "time" ) @@ -18,20 +24,56 @@ func TestName(t *testing.T) { panic(err) } min := tmp.(*Minio) - cli := min.core.Client - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) - defer cancel() - policy := minio.NewPostPolicy() - _ = policy.SetExpires(time.Now().Add(time.Hour)) - _ = policy.SetKey("test.txt") - _ = policy.SetBucket(config.Config.Object.Minio.Bucket) - policy.SetContentType("text/plain") - u, fd, err := cli.PresignedPostPolicy(ctx, policy) + + text := []byte("hello world!") + name := "posttest.txt" + + u, err := min.FormData(context.Background(), "posttest.txt", int64(len(text)), "image/png", time.Second*1000) if err != nil { panic(err) } - t.Log(u) - for k, v := range fd { + t.Log(u.URL) + for k, v := range u.FormData { t.Log(k, v) } + if err := PostFile(u, name, text); err != nil { + t.Error(err) + } +} + +func PostFile(fd *s3.FormData, name string, data []byte) error { + var body bytes.Buffer + writer := multipart.NewWriter(&body) + for k, v := range fd.FormData { + if err := writer.WriteField(k, v); err != nil { + return err + } + } + fileWriter, err := writer.CreateFormFile(fd.File, path.Base(name)) + if err != nil { + return err + } + if _, err := fileWriter.Write(data); err != nil { + return nil + } + defer writer.Close() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + reqBody := body.Bytes() + req, err := http.NewRequestWithContext(ctx, http.MethodPost, fd.URL, bytes.NewReader(reqBody)) + req.Header.Set("Content-Type", writer.FormDataContentType()) + req.ContentLength = int64(len(reqBody)) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + if resp.StatusCode != http.StatusOK { + return errors.New(string(respBody)) + } + return nil } diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go index a4c34fa826..710991bb62 100644 --- a/pkg/common/db/s3/oss/oss.go +++ b/pkg/common/db/s3/oss/oss.go @@ -16,8 +16,13 @@ package oss import ( "context" + "crypto/hmac" + "crypto/sha1" + "encoding/base64" + "encoding/json" "errors" "fmt" + "io" "net/http" "net/url" "reflect" @@ -45,6 +50,8 @@ const ( imageWebp = "webp" ) +const successCode = http.StatusOK + const ( videoSnapshotImagePng = "png" videoSnapshotImageJpg = "jpg" @@ -329,5 +336,37 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, } func (o *OSS) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { - return nil, errors.New("oss temporarily not supported") + // https://help.aliyun.com/zh/oss/developer-reference/postobject?spm=a2c4g.11186623.0.0.1cb83cebkP55nn + expires := time.Now().Add(duration) + policy := map[string]any{ + "expiration": expires.Format("2006-01-02T15:04:05.000Z"), + "conditions": []any{ + map[string]string{"bucket": o.bucket.BucketName}, + []any{"content-length-range", 0, size}, + //map[string]string{"content-type": contentType}, + }, + } + policyJson, err := json.Marshal(policy) + if err != nil { + return nil, err + } + policyStr := base64.StdEncoding.EncodeToString(policyJson) + h := hmac.New(sha1.New, []byte(o.credentials.GetAccessKeySecret())) + if _, err := io.WriteString(h, policyStr); err != nil { + return nil, err + } + fd := &s3.FormData{ + URL: o.bucketURL, + File: "file", + Expires: expires, + FormData: map[string]string{ + "key": name, + "policy": policyStr, + "OSSAccessKeyId": o.credentials.GetAccessKeyID(), + "success_action_status": strconv.Itoa(successCode), + "signature": base64.StdEncoding.EncodeToString(h.Sum(nil)), + }, + SuccessCodes: []int{successCode}, + } + return fd, nil } diff --git a/pkg/common/db/s3/s3.go b/pkg/common/db/s3/s3.go index 3ca29943b3..0352004b58 100644 --- a/pkg/common/db/s3/s3.go +++ b/pkg/common/db/s3/s3.go @@ -75,11 +75,12 @@ type CopyObjectInfo struct { } type FormData struct { - URL string `json:"url"` - File string `json:"file"` - Header http.Header `json:"header"` - FormData map[string]string `json:"form"` - Expires time.Time `json:"expires"` + URL string `json:"url"` + File string `json:"file"` + Header http.Header `json:"header"` + FormData map[string]string `json:"form"` + Expires time.Time `json:"expires"` + SuccessCodes []int `json:"successActionStatus"` } type SignPart struct { From 9b84e417a027986b957262b851f85f545008ae0c Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 14:54:52 +0800 Subject: [PATCH 08/14] s3 form data --- go.mod | 2 +- go.sum | 10 ---- pkg/common/db/s3/cos/cos.go | 55 +++++++------------ pkg/common/db/s3/minio/minio.go | 6 ++- pkg/common/db/s3/minio/minio_test.go | 79 ---------------------------- pkg/common/db/s3/oss/oss.go | 16 ++++-- 6 files changed, 35 insertions(+), 133 deletions(-) delete mode 100644 pkg/common/db/s3/minio/minio_test.go diff --git a/go.mod b/go.mod index 8e8b425a45..9047640968 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require github.com/google/uuid v1.3.1 require ( github.com/IBM/sarama v1.41.3 - github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible + github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/go-redis/redis v6.15.9+incompatible github.com/redis/go-redis/v9 v9.2.1 github.com/tencentyun/cos-go-sdk-v5 v0.7.45 diff --git a/go.sum b/go.sum index 6faa5d97c0..125bc28df4 100644 --- a/go.sum +++ b/go.sum @@ -25,8 +25,6 @@ github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBb github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible h1:Sg/2xHwDrioHpxTN6WMiwbXTpUEinBpHsN7mG21Rc2k= github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= -github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible h1:so4m5rRA32Tc5GgKg/5gKUu0CRsYmVO3ThMP6T3CwLc= -github.com/aliyun/aliyun-oss-go-sdk v3.0.1+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -91,7 +89,6 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -199,10 +196,8 @@ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -255,7 +250,6 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w= github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -384,7 +378,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -456,8 +449,6 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -471,7 +462,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/common/db/s3/cos/cos.go b/pkg/common/db/s3/cos/cos.go index 15d7c57d39..7d2c0befe9 100644 --- a/pkg/common/db/s3/cos/cos.go +++ b/pkg/common/db/s3/cos/cos.go @@ -23,7 +23,6 @@ import ( "encoding/json" "errors" "fmt" - "io" "net/http" "net/url" "strconv" @@ -336,68 +335,52 @@ func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Dura } func (c *Cos) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { - //res, _, err := c.client.Object.ListUploads(ctx, &cos.ObjectListUploadsOptions{}) - //if err != nil { - // return nil, err - //} + // https://cloud.tencent.com/document/product/436/14690 now := time.Now() expiration := now.Add(duration) keyTime := fmt.Sprintf("%d;%d", now.Unix(), expiration.Unix()) conditions := []any{ - map[string]string{"success_action_status": strconv.Itoa(successCode)}, - []any{"content-length-range", 0, size}, + map[string]string{"q-sign-algorithm": "sha1"}, + map[string]string{"q-ak": c.credential.SecretID}, map[string]string{"q-sign-time": keyTime}, map[string]string{"key": name}, - map[string]string{"q-sign-algorithm": "sha1"}, } - if c.credential.SessionToken != "" { - conditions = append(conditions, map[string]string{"x-cos-security-token": c.credential.SessionToken}) + if contentType != "" { + conditions = append(conditions, map[string]string{"Content-Type": contentType}) } policy := map[string]any{ "expiration": expiration.Format("2006-01-02T15:04:05.000Z"), - "conditions": []any{ - //map[string]string{"bucket": res.Bucket}, - //map[string]string{"acl": "default"}, - map[string]string{"q-sign-algorithm": "sha1"}, - map[string]string{"q-ak": c.credential.SecretID}, - map[string]string{"q-sign-time": keyTime}, - - //map[string]string{"success_action_status": strconv.Itoa(successCode)}, - //[]any{"content-length-range", 0, size}, - //map[string]string{"key": name}, - //map[string]string{"x-cos-security-token": c.credential.SessionToken}, - }, + "conditions": conditions, } policyJson, err := json.Marshal(policy) if err != nil { return nil, err } - //signKey := hmacSha1val(c.credential.SecretKey, keyTime) - //policyStr := hmacSha1val(sha1val(signKey), string(policyJson)) + signKey := hmacSha1val(c.credential.SecretKey, keyTime) + strToSign := sha1val(string(policyJson)) + signature := hmacSha1val(signKey, strToSign) - policyStr := base64.StdEncoding.EncodeToString(policyJson) - h := hmac.New(sha1.New, []byte(c.credential.SecretKey)) - if _, err := io.WriteString(h, policyStr); err != nil { - return nil, err - } fd := &s3.FormData{ URL: c.client.BaseURL.BucketURL.String(), File: "file", Expires: expiration, FormData: map[string]string{ - "key": name, - "policy": policyStr, - "q-sign-algorithm": "sha1", - "q-ak": c.credential.SecretID, - "q-key-time": keyTime, - "q-signature": hex.EncodeToString(h.Sum(nil)), + "policy": base64.StdEncoding.EncodeToString(policyJson), + "q-sign-algorithm": "sha1", + "q-ak": c.credential.SecretID, + "q-key-time": keyTime, + "q-signature": signature, + "key": name, + "success_action_status": strconv.Itoa(successCode), }, SuccessCodes: []int{successCode}, } + if contentType != "" { + fd.FormData["Content-Type"] = contentType + } if c.credential.SessionToken != "" { fd.FormData["x-cos-security-token"] = c.credential.SessionToken } - // 2019-08-30 17:38:12 return fd, nil } diff --git a/pkg/common/db/s3/minio/minio.go b/pkg/common/db/s3/minio/minio.go index 4300520580..4bd2acb3b2 100644 --- a/pkg/common/db/s3/minio/minio.go +++ b/pkg/common/db/s3/minio/minio.go @@ -456,8 +456,10 @@ func (m *Minio) FormData(ctx context.Context, name string, size int64, contentTy if err := policy.SetExpires(expires); err != nil { return nil, err } - if err := policy.SetContentLengthRange(0, size); err != nil { - return nil, err + if size > 0 { + if err := policy.SetContentLengthRange(0, size); err != nil { + return nil, err + } } if err := policy.SetSuccessStatusAction(strconv.Itoa(successCode)); err != nil { return nil, err diff --git a/pkg/common/db/s3/minio/minio_test.go b/pkg/common/db/s3/minio/minio_test.go deleted file mode 100644 index 0780c40212..0000000000 --- a/pkg/common/db/s3/minio/minio_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package minio - -import ( - "bytes" - "context" - "errors" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" - "io" - "mime/multipart" - "net/http" - "path" - "testing" - "time" -) - -func TestName(t *testing.T) { - config.Config.Object.Minio.Bucket = "openim" - config.Config.Object.Minio.AccessKeyID = "root" - config.Config.Object.Minio.SecretAccessKey = "openIM123" - config.Config.Object.Minio.Endpoint = "http://172.16.8.38:10005" - tmp, err := NewMinio(nil) - if err != nil { - panic(err) - } - min := tmp.(*Minio) - - text := []byte("hello world!") - name := "posttest.txt" - - u, err := min.FormData(context.Background(), "posttest.txt", int64(len(text)), "image/png", time.Second*1000) - if err != nil { - panic(err) - } - t.Log(u.URL) - for k, v := range u.FormData { - t.Log(k, v) - } - if err := PostFile(u, name, text); err != nil { - t.Error(err) - } -} - -func PostFile(fd *s3.FormData, name string, data []byte) error { - var body bytes.Buffer - writer := multipart.NewWriter(&body) - for k, v := range fd.FormData { - if err := writer.WriteField(k, v); err != nil { - return err - } - } - fileWriter, err := writer.CreateFormFile(fd.File, path.Base(name)) - if err != nil { - return err - } - if _, err := fileWriter.Write(data); err != nil { - return nil - } - defer writer.Close() - ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) - defer cancel() - reqBody := body.Bytes() - req, err := http.NewRequestWithContext(ctx, http.MethodPost, fd.URL, bytes.NewReader(reqBody)) - req.Header.Set("Content-Type", writer.FormDataContentType()) - req.ContentLength = int64(len(reqBody)) - resp, err := http.DefaultClient.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - if resp.StatusCode != http.StatusOK { - return errors.New(string(respBody)) - } - return nil -} diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go index 710991bb62..8fa2a538e8 100644 --- a/pkg/common/db/s3/oss/oss.go +++ b/pkg/common/db/s3/oss/oss.go @@ -338,13 +338,16 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, func (o *OSS) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) { // https://help.aliyun.com/zh/oss/developer-reference/postobject?spm=a2c4g.11186623.0.0.1cb83cebkP55nn expires := time.Now().Add(duration) + conditions := []any{ + map[string]string{"bucket": o.bucket.BucketName}, + map[string]string{"key": name}, + } + if size > 0 { + conditions = append(conditions, []any{"content-length-range", 0, size}) + } policy := map[string]any{ "expiration": expires.Format("2006-01-02T15:04:05.000Z"), - "conditions": []any{ - map[string]string{"bucket": o.bucket.BucketName}, - []any{"content-length-range", 0, size}, - //map[string]string{"content-type": contentType}, - }, + "conditions": conditions, } policyJson, err := json.Marshal(policy) if err != nil { @@ -368,5 +371,8 @@ func (o *OSS) FormData(ctx context.Context, name string, size int64, contentType }, SuccessCodes: []int{successCode}, } + if contentType != "" { + fd.FormData["x-oss-content-type"] = contentType + } return fd, nil } From a22004cb0964104fcaa9304923ab1bb475aa7245 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 14:59:20 +0800 Subject: [PATCH 09/14] s3 form data --- internal/rpc/third/s3.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index 14d1d51767..2c230f258b 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -185,8 +185,6 @@ func (t *thirdServer) AccessURL(ctx context.Context, req *third.AccessURLReq) (* }, nil } -const direct = "direct" - func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateFormDataReq) (*third.InitiateFormDataResp, error) { if req.Name == "" { return nil, errs.ErrArgs.Wrap("name is empty") @@ -242,6 +240,9 @@ func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateF Header: toPbMapArray(resp.Header), FormData: resp.FormData, Expires: resp.Expires.UnixMilli(), + SuccessCodes: utils.Slice(resp.SuccessCodes, func(code int) int32 { + return int32(code) + }), }, nil } From 407ebdc6418505e887956a057f1d6d0faccdc1c0 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 15:03:09 +0800 Subject: [PATCH 10/14] s3 form data --- go.mod | 4 +--- go.sum | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9047640968..569d49985f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( firebase.google.com/go v3.13.0+incompatible - github.com/OpenIMSDK/protocol v0.0.35 + github.com/OpenIMSDK/protocol v0.0.38 github.com/OpenIMSDK/tools v0.0.20 github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/dtm-labs/rockscache v0.1.1 @@ -154,5 +154,3 @@ require ( golang.org/x/crypto v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) - -replace github.com/OpenIMSDK/protocol => C:\Users\openIM\Desktop\fork\protocol diff --git a/go.sum b/go.sum index 125bc28df4..be9c3b2211 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= +github.com/OpenIMSDK/protocol v0.0.38 h1:td2EB6ZUIrZkiR58O4IOcm4Tyh5Zbl4GAlPjXiPPLcg= +github.com/OpenIMSDK/protocol v0.0.38/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/tools v0.0.20 h1:zBTjQZRJ5lR1FIzP9mtWyAvh5dKsmJXQugi4p8X/97k= github.com/OpenIMSDK/tools v0.0.20/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= From 10f385247342c571ea7ac32b7e743845fc66404b Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 15:07:45 +0800 Subject: [PATCH 11/14] s3 form data --- internal/rpc/friend/friend.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 21422fae30..b2607af59a 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -52,8 +52,8 @@ type friendServer struct { RegisterCenter registry.SvcDiscoveryRegistry } -func (s *friendServer) PinFriends(ctx context.Context, req *pbfriend.PinFriendsReq) (*pbfriend.PinFriendsResp, error) { - return nil, errs.ErrInternalServer.Wrap("not implemented") +func (s *friendServer) UpdateFriends(ctx context.Context, req *pbfriend.UpdateFriendsReq) (*pbfriend.UpdateFriendsResp, error) { + return nil, errs.ErrInternalServer.Wrap("implement me") } func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { From 275cf7f528e611c41b3e87a12a5d82624a46af87 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 15:10:13 +0800 Subject: [PATCH 12/14] s3 form data --- internal/rpc/friend/friend.go | 2 +- internal/rpc/user/user.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index b2607af59a..967574db23 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -53,7 +53,7 @@ type friendServer struct { } func (s *friendServer) UpdateFriends(ctx context.Context, req *pbfriend.UpdateFriendsReq) (*pbfriend.UpdateFriendsResp, error) { - return nil, errs.ErrInternalServer.Wrap("implement me") + return nil, errs.ErrInternalServer.Wrap("not implemented") } func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index a2fa14c7a4..d90d5ddbac 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -56,6 +56,10 @@ type userServer struct { RegisterCenter registry.SvcDiscoveryRegistry } +func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (*pbuser.UpdateUserInfoExResp, error) { + return nil, errs.ErrInternalServer.Wrap("not implemented") +} + func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) { return nil, errs.ErrInternalServer.Wrap("not implemented") } From bf53582ffcfbaf6695aed2816e44a5898bac2457 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 15:52:03 +0800 Subject: [PATCH 13/14] s3 form data --- pkg/common/db/s3/minio/minio.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/common/db/s3/minio/minio.go b/pkg/common/db/s3/minio/minio.go index 4bd2acb3b2..7dfe35b513 100644 --- a/pkg/common/db/s3/minio/minio.go +++ b/pkg/common/db/s3/minio/minio.go @@ -476,6 +476,12 @@ func (m *Minio) FormData(ctx context.Context, name string, size int64, contentTy if err != nil { return nil, err } + sign, err := url.Parse(m.signEndpoint) + if err != nil { + return nil, err + } + u.Scheme = sign.Scheme + u.Host = sign.Host return &s3.FormData{ URL: u.String(), File: "file", From 1c96aa177cb95f16e676b4df880ea9ff21a29512 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Tue, 26 Dec 2023 17:08:09 +0800 Subject: [PATCH 14/14] s3 form data --- go.mod | 2 +- go.sum | 8 ++++---- internal/rpc/third/third.go | 10 ---------- internal/rpc/user/user.go | 21 --------------------- 4 files changed, 5 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 1221a29933..a753cae518 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.19 require ( firebase.google.com/go v3.13.0+incompatible - github.com/OpenIMSDK/protocol v0.0.38 + github.com/OpenIMSDK/protocol v0.0.39 github.com/OpenIMSDK/tools v0.0.21 github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/dtm-labs/rockscache v0.1.1 diff --git a/go.sum b/go.sum index cde33c7cd5..a4609f6f2f 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIw github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c= github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ= +github.com/OpenIMSDK/protocol v0.0.39 h1:DfvFcNGBcfj2vtT7W3uw4U/ipnI7NecTzQdlSYGuQz8= +github.com/OpenIMSDK/protocol v0.0.39/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/OpenIMSDK/tools v0.0.21 h1:iTapc2mIEVH/xl5Nd6jfwPub11Pgp44tVcE1rjB3a48= github.com/OpenIMSDK/tools v0.0.21/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI= github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= @@ -225,8 +227,6 @@ github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205Ah github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= github.com/lithammer/shortuuid v3.0.0+incompatible h1:NcD0xWW/MZYXEHa6ITy6kaXN5nwm/V115vj2YXfhS0w= github.com/lithammer/shortuuid v3.0.0+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w= -github.com/luhaoling/protocol v0.0.0-20231222100538-d625562d53d5 h1:nmrJmAgQsCAxKgw109kaTcBV4rMWDRvqOson0ehw708= -github.com/luhaoling/protocol v0.0.0-20231222100538-d625562d53d5/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -453,8 +453,8 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index 35df3f9259..7a63d3526a 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -101,16 +101,6 @@ type thirdServer struct { defaultExpire time.Duration } -func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateFormDataReq) (*third.InitiateFormDataResp, error) { - //TODO implement me - panic("implement me") -} - -func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.CompleteFormDataReq) (*third.CompleteFormDataResp, error) { - //TODO implement me - panic("implement me") -} - func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) { err = t.thirdDatabase.FcmUpdateToken(ctx, req.Account, int(req.PlatformID), req.FcmToken, req.ExpireTime) if err != nil { diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index b5a5714146..b5ad186a5d 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -61,22 +61,6 @@ func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUse return nil, errs.ErrInternalServer.Wrap("not implemented") } -func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) { - return nil, errs.ErrInternalServer.Wrap("not implemented") -} - -func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) { - return nil, errs.ErrInternalServer.Wrap("not implemented") -} - -func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) { - return nil, errs.ErrInternalServer.Wrap("not implemented") -} - -func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) { - return nil, errs.ErrInternalServer.Wrap("not implemented") -} - func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { rdb, err := cache.NewRedis() if err != nil { @@ -504,11 +488,6 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser. return &pbuser.SearchNotificationAccountResp{Total: total, NotificationAccounts: accounts}, nil } -func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (*pbuser.UpdateUserInfoExResp, error) { - //TODO implement me - panic("implement me") -} - func (s *userServer) GetNotificationAccount(ctx context.Context, req *pbuser.GetNotificationAccountReq) (*pbuser.GetNotificationAccountResp, error) { if req.UserID == "" { return nil, errs.ErrArgs.Wrap("userID is empty")