feat: ApplicationVersion move chat (#2813)
* fix: GroupApplicationAcceptedNotification * fix: GroupApplicationAcceptedNotification * fix: NotificationUserInfoUpdate * cicd: robot automated Change * fix: component * fix: getConversationInfo * feat: cron task * feat: cron task * feat: cron task * feat: cron task * feat: cron task * fix: minio config url recognition error * update gomake version * update gomake version * fix: seq conversion bug * fix: redis pipe exec * fix: ImportFriends * fix: A large number of logs keysAndValues length is not even * feat: mark read aggregate write * feat: online status supports redis cluster * feat: online status supports redis cluster * feat: online status supports redis cluster * merge * merge * read seq is written to mongo * read seq is written to mongo * fix: invitation to join group notification * fix: friend op_user_id * feat: optimizing asynchronous context * feat: optimizing memamq size * feat: add GetSeqMessage * feat: GroupApplicationAgreeMemberEnterNotification * feat: GroupApplicationAgreeMemberEnterNotification * feat: go.mod * feat: go.mod * feat: join group notification and get seq * feat: join group notification and get seq * feat: avoid pulling messages from sessions with a large number of max seq values of 0 * feat: API supports gzip * go.mod * fix: nil pointer error on close * fix: listen error * fix: listen error * update go.mod * feat: add log * fix: token parse token value * fix: GetMsgBySeqs boundary issues * fix: sn_ not sort * fix: sn_ not sort * fix: sn_ not sort * fix: jssdk add * fix: jssdk support * fix: jssdk support * fix: jssdk support * fix: the message I sent is not set to read seq in mongodb * fix: cannot modify group member avatars * fix: MemberEnterNotification * fix: MemberEnterNotification * fix: MsgData status * feat: add ApplicationVersion * feat: ApplicationVersion move chat --------- Co-authored-by: withchao <withchao@users.noreply.github.com>pull/2815/head
parent
ea477fd91f
commit
61fc9bffec
@ -1,136 +0,0 @@
|
|||||||
package third
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"github.com/openimsdk/protocol/third"
|
|
||||||
"github.com/openimsdk/tools/errs"
|
|
||||||
"github.com/openimsdk/tools/utils/datautil"
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func IsNotFound(err error) bool {
|
|
||||||
switch errs.Unwrap(err) {
|
|
||||||
case redis.Nil, mongo.ErrNoDocuments:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) db2pbApplication(val *model.Application) *third.ApplicationVersion {
|
|
||||||
return &third.ApplicationVersion{
|
|
||||||
Id: val.ID.Hex(),
|
|
||||||
Platform: val.Platform,
|
|
||||||
Version: val.Version,
|
|
||||||
Url: val.Url,
|
|
||||||
Text: val.Text,
|
|
||||||
Force: val.Force,
|
|
||||||
Latest: val.Latest,
|
|
||||||
Hot: val.Hot,
|
|
||||||
CreateTime: val.CreateTime.UnixMilli(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) getLatestApplicationVersion(ctx context.Context, platform string, hot bool) (*third.ApplicationVersion, error) {
|
|
||||||
res, err := t.applicationDatabase.LatestVersion(ctx, platform, hot)
|
|
||||||
if err == nil {
|
|
||||||
return t.db2pbApplication(res), nil
|
|
||||||
} else if IsNotFound(err) {
|
|
||||||
return nil, nil
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) LatestApplicationVersion(ctx context.Context, req *third.LatestApplicationVersionReq) (*third.LatestApplicationVersionResp, error) {
|
|
||||||
var (
|
|
||||||
resp third.LatestApplicationVersionResp
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
resp.Version, err = t.getLatestApplicationVersion(ctx, req.Platform, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp.Hot, err = t.getLatestApplicationVersion(ctx, req.Platform, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) AddApplicationVersion(ctx context.Context, req *third.AddApplicationVersionReq) (*third.AddApplicationVersionResp, error) {
|
|
||||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
val := &model.Application{
|
|
||||||
ID: primitive.NewObjectID(),
|
|
||||||
Platform: req.Platform,
|
|
||||||
Version: req.Version,
|
|
||||||
Url: req.Url,
|
|
||||||
Text: req.Text,
|
|
||||||
Force: req.Force,
|
|
||||||
Latest: req.Latest,
|
|
||||||
Hot: req.Hot,
|
|
||||||
CreateTime: time.Now(),
|
|
||||||
}
|
|
||||||
if err := t.applicationDatabase.AddVersion(ctx, val); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &third.AddApplicationVersionResp{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) UpdateApplicationVersion(ctx context.Context, req *third.UpdateApplicationVersionReq) (*third.UpdateApplicationVersionResp, error) {
|
|
||||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
oid, err := primitive.ObjectIDFromHex(req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("invalid id " + err.Error())
|
|
||||||
}
|
|
||||||
update := make(map[string]any)
|
|
||||||
putUpdate(update, "platform", req.Platform)
|
|
||||||
putUpdate(update, "version", req.Version)
|
|
||||||
putUpdate(update, "url", req.Url)
|
|
||||||
putUpdate(update, "text", req.Text)
|
|
||||||
putUpdate(update, "force", req.Force)
|
|
||||||
putUpdate(update, "latest", req.Latest)
|
|
||||||
putUpdate(update, "hot", req.Hot)
|
|
||||||
if err := t.applicationDatabase.UpdateVersion(ctx, oid, update); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &third.UpdateApplicationVersionResp{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) DeleteApplicationVersion(ctx context.Context, req *third.DeleteApplicationVersionReq) (*third.DeleteApplicationVersionResp, error) {
|
|
||||||
if err := authverify.CheckAdmin(ctx, t.config.Share.IMAdminUserID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ids := make([]primitive.ObjectID, 0, len(req.Id))
|
|
||||||
for _, id := range req.Id {
|
|
||||||
oid, err := primitive.ObjectIDFromHex(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errs.ErrArgs.WrapMsg("invalid id " + err.Error())
|
|
||||||
}
|
|
||||||
ids = append(ids, oid)
|
|
||||||
}
|
|
||||||
if err := t.applicationDatabase.DeleteVersion(ctx, ids); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &third.DeleteApplicationVersionResp{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *thirdServer) PageApplicationVersion(ctx context.Context, req *third.PageApplicationVersionReq) (*third.PageApplicationVersionResp, error) {
|
|
||||||
total, res, err := t.applicationDatabase.PageVersion(ctx, req.Platform, req.Pagination)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &third.PageApplicationVersionResp{
|
|
||||||
Total: total,
|
|
||||||
Versions: datautil.Slice(res, t.db2pbApplication),
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ApplicationCache interface {
|
|
||||||
LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
|
|
||||||
DeleteCache(ctx context.Context, platforms []string) error
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package cachekey
|
|
||||||
|
|
||||||
const (
|
|
||||||
ApplicationLatestVersion = "APPLICATION_LATEST_VERSION:"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetApplicationLatestVersionKey(platform string, hot bool) string {
|
|
||||||
var hotStr string
|
|
||||||
if hot {
|
|
||||||
hotStr = "1:"
|
|
||||||
} else {
|
|
||||||
hotStr = "0:"
|
|
||||||
}
|
|
||||||
return ApplicationLatestVersion + hotStr + platform
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package redis
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/dtm-labs/rockscache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewApplicationRedisCache(db database.Application, rdb redis.UniversalClient) *ApplicationRedisCache {
|
|
||||||
return &ApplicationRedisCache{
|
|
||||||
db: db,
|
|
||||||
rcClient: rockscache.NewClient(rdb, *GetRocksCacheOptions()),
|
|
||||||
deleter: NewBatchDeleterRedis(rdb, GetRocksCacheOptions(), nil),
|
|
||||||
expireTime: time.Hour * 24 * 7,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApplicationRedisCache struct {
|
|
||||||
db database.Application
|
|
||||||
rcClient *rockscache.Client
|
|
||||||
deleter *BatchDeleterRedis
|
|
||||||
expireTime time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationRedisCache) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
|
|
||||||
return getCache(ctx, a.rcClient, cachekey.GetApplicationLatestVersionKey(platform, hot), a.expireTime, func(ctx context.Context) (*model.Application, error) {
|
|
||||||
return a.db.LatestVersion(ctx, platform, hot)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationRedisCache) DeleteCache(ctx context.Context, platforms []string) error {
|
|
||||||
if len(platforms) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
keys := make([]string, 0, len(platforms)*2)
|
|
||||||
for _, platform := range platforms {
|
|
||||||
keys = append(keys, cachekey.GetApplicationLatestVersionKey(platform, true), cachekey.GetApplicationLatestVersionKey(platform, false))
|
|
||||||
}
|
|
||||||
return a.deleter.ExecDelWithKeys(ctx, keys)
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package controller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/database"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ApplicationDatabase interface {
|
|
||||||
LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
|
|
||||||
AddVersion(ctx context.Context, val *model.Application) error
|
|
||||||
UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error
|
|
||||||
DeleteVersion(ctx context.Context, id []primitive.ObjectID) error
|
|
||||||
PageVersion(ctx context.Context, platforms []string, page pagination.Pagination) (int64, []*model.Application, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewApplicationDatabase(db database.Application, cache cache.ApplicationCache) ApplicationDatabase {
|
|
||||||
return &applicationDatabase{db: db, cache: cache}
|
|
||||||
}
|
|
||||||
|
|
||||||
type applicationDatabase struct {
|
|
||||||
db database.Application
|
|
||||||
cache cache.ApplicationCache
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *applicationDatabase) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
|
|
||||||
return a.cache.LatestVersion(ctx, platform, hot)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *applicationDatabase) AddVersion(ctx context.Context, val *model.Application) error {
|
|
||||||
if err := a.db.AddVersion(ctx, val); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return a.cache.DeleteCache(ctx, []string{val.Platform})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *applicationDatabase) UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error {
|
|
||||||
platforms, err := a.db.FindPlatform(ctx, []primitive.ObjectID{id})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := a.db.UpdateVersion(ctx, id, update); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if p, ok := update["platform"]; ok {
|
|
||||||
if val, ok := p.(string); ok {
|
|
||||||
platforms = append(platforms, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return a.cache.DeleteCache(ctx, platforms)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *applicationDatabase) DeleteVersion(ctx context.Context, id []primitive.ObjectID) error {
|
|
||||||
platforms, err := a.db.FindPlatform(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := a.db.DeleteVersion(ctx, id); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return a.cache.DeleteCache(ctx, platforms)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *applicationDatabase) PageVersion(ctx context.Context, platforms []string, page pagination.Pagination) (int64, []*model.Application, error) {
|
|
||||||
return a.db.PageVersion(ctx, platforms, page)
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Application interface {
|
|
||||||
LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error)
|
|
||||||
AddVersion(ctx context.Context, val *model.Application) error
|
|
||||||
UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error
|
|
||||||
DeleteVersion(ctx context.Context, id []primitive.ObjectID) error
|
|
||||||
PageVersion(ctx context.Context, platforms []string, page pagination.Pagination) (int64, []*model.Application, error)
|
|
||||||
FindPlatform(ctx context.Context, id []primitive.ObjectID) ([]string, error)
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package mgo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/storage/model"
|
|
||||||
"github.com/openimsdk/tools/db/mongoutil"
|
|
||||||
"github.com/openimsdk/tools/db/pagination"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewApplicationMgo(db *mongo.Database) (*ApplicationMgo, error) {
|
|
||||||
coll := db.Collection("application")
|
|
||||||
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
|
|
||||||
{
|
|
||||||
Keys: bson.D{
|
|
||||||
{Key: "platform", Value: 1},
|
|
||||||
{Key: "version", Value: 1},
|
|
||||||
{Key: "hot", Value: 1},
|
|
||||||
},
|
|
||||||
Options: options.Index().SetUnique(true),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Keys: bson.D{
|
|
||||||
{Key: "latest", Value: -1},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ApplicationMgo{coll: coll}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApplicationMgo struct {
|
|
||||||
coll *mongo.Collection
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) sort() any {
|
|
||||||
return bson.D{{"latest", -1}, {"_id", -1}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) LatestVersion(ctx context.Context, platform string, hot bool) (*model.Application, error) {
|
|
||||||
return mongoutil.FindOne[*model.Application](ctx, a.coll, bson.M{"platform": platform, "hot": hot}, options.FindOne().SetSort(a.sort()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) AddVersion(ctx context.Context, val *model.Application) error {
|
|
||||||
if val.ID.IsZero() {
|
|
||||||
val.ID = primitive.NewObjectID()
|
|
||||||
}
|
|
||||||
return mongoutil.InsertMany(ctx, a.coll, []*model.Application{val})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error {
|
|
||||||
if len(update) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return mongoutil.UpdateOne(ctx, a.coll, bson.M{"_id": id}, bson.M{"$set": update}, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) DeleteVersion(ctx context.Context, id []primitive.ObjectID) error {
|
|
||||||
if len(id) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return mongoutil.DeleteMany(ctx, a.coll, bson.M{"_id": bson.M{"$in": id}})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) PageVersion(ctx context.Context, platforms []string, page pagination.Pagination) (int64, []*model.Application, error) {
|
|
||||||
filter := bson.M{}
|
|
||||||
if len(platforms) > 0 {
|
|
||||||
filter["platform"] = bson.M{"$in": platforms}
|
|
||||||
}
|
|
||||||
return mongoutil.FindPage[*model.Application](ctx, a.coll, filter, page, options.Find().SetSort(a.sort()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplicationMgo) FindPlatform(ctx context.Context, id []primitive.ObjectID) ([]string, error) {
|
|
||||||
if len(id) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return mongoutil.Find[string](ctx, a.coll, bson.M{"_id": bson.M{"$in": id}}, options.Find().SetProjection(bson.M{"_id": 0, "platform": 1}))
|
|
||||||
}
|
|
Loading…
Reference in new issue