Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support app update service #612

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions internal/api/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -566,3 +566,23 @@ func (o *Api) SetAllowRegister(c *gin.Context) {
func (o *Api) GetAllowRegister(c *gin.Context) {
a2r.Call(chat.ChatClient.GetAllowRegister, o.chatClient, c)
}

func (o *Api) LatestApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.LatestApplicationVersion, o.adminClient, c)
}

func (o *Api) PageApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.PageApplicationVersion, o.adminClient, c)
}

func (o *Api) AddApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.AddApplicationVersion, o.adminClient, c)
}

func (o *Api) UpdateApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.UpdateApplicationVersion, o.adminClient, c)
}

func (o *Api) DeleteApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.DeleteApplicationVersion, o.adminClient, c)
}
7 changes: 7 additions & 0 deletions internal/api/admin/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,11 @@ func SetAdminRoute(router gin.IRouter, admin *Api, mw *chatmw.MW) {
statistic := router.Group("/statistic", mw.CheckAdmin)
statistic.POST("/new_user_count", admin.NewUserCount)
statistic.POST("/login_user_count", admin.LoginUserCount)

applicationGroup := router.Group("application")
applicationGroup.POST("/add_version", mw.CheckAdmin, admin.AddApplicationVersion)
applicationGroup.POST("/update_version", mw.CheckAdmin, admin.UpdateApplicationVersion)
applicationGroup.POST("/delete_version", mw.CheckAdmin, admin.DeleteApplicationVersion)
applicationGroup.POST("/latest_version", admin.LatestApplicationVersion)
applicationGroup.POST("/page_versions", admin.PageApplicationVersion)
}
8 changes: 8 additions & 0 deletions internal/api/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,11 @@ func (o *Api) SearchFriend(c *gin.Context) {
}
apiresp.GinSuccess(c, resp)
}

func (o *Api) LatestApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.LatestApplicationVersion, o.adminClient, c)
}

func (o *Api) PageApplicationVersion(c *gin.Context) {
a2r.Call(admin.AdminClient.PageApplicationVersion, o.adminClient, c)
}
4 changes: 4 additions & 0 deletions internal/api/chat/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,9 @@ func SetChatRoute(router gin.IRouter, chat *Api, mw *chatmw.MW) {

router.Group("/client_config").POST("/get", chat.GetClientConfig) // Get client initialization configuration

applicationGroup := router.Group("application")
applicationGroup.POST("/latest_version", chat.LatestApplicationVersion)
applicationGroup.POST("/page_versions", chat.PageApplicationVersion)

router.Group("/callback").POST("/open_im", chat.OpenIMCallback) // Callback
}
128 changes: 128 additions & 0 deletions internal/rpc/admin/application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package admin

import (
"context"
admindb "github.com/openimsdk/chat/pkg/common/db/table/admin"
"github.com/openimsdk/chat/pkg/common/mctx"
"github.com/openimsdk/chat/pkg/protocol/admin"
"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 (o *adminServer) db2pbApplication(val *admindb.Application) *admin.ApplicationVersion {
return &admin.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 (o *adminServer) LatestApplicationVersion(ctx context.Context, req *admin.LatestApplicationVersionReq) (*admin.LatestApplicationVersionResp, error) {
res, err := o.Database.LatestVersion(ctx, req.Platform)
if err == nil {
return &admin.LatestApplicationVersionResp{Version: o.db2pbApplication(res)}, nil
} else if IsNotFound(err) {
return &admin.LatestApplicationVersionResp{}, nil
} else {
return nil, err
}
}

func (o *adminServer) AddApplicationVersion(ctx context.Context, req *admin.AddApplicationVersionReq) (*admin.AddApplicationVersionResp, error) {
if _, err := mctx.CheckAdmin(ctx); err != nil {
return nil, err
}
val := &admindb.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 := o.Database.AddVersion(ctx, val); err != nil {
return nil, err
}
return &admin.AddApplicationVersionResp{}, nil
}

func (o *adminServer) UpdateApplicationVersion(ctx context.Context, req *admin.UpdateApplicationVersionReq) (*admin.UpdateApplicationVersionResp, error) {
if _, err := mctx.CheckAdmin(ctx); 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 := o.Database.UpdateVersion(ctx, oid, update); err != nil {
return nil, err
}
return &admin.UpdateApplicationVersionResp{}, nil
}

func (o *adminServer) DeleteApplicationVersion(ctx context.Context, req *admin.DeleteApplicationVersionReq) (*admin.DeleteApplicationVersionResp, error) {
if _, err := mctx.CheckAdmin(ctx); 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 := o.Database.DeleteVersion(ctx, ids); err != nil {
return nil, err
}
return &admin.DeleteApplicationVersionResp{}, nil
}

func (o *adminServer) PageApplicationVersion(ctx context.Context, req *admin.PageApplicationVersionReq) (*admin.PageApplicationVersionResp, error) {
total, res, err := o.Database.PageVersion(ctx, req.Platform, req.Pagination)
if err != nil {
return nil, err
}
return &admin.PageApplicationVersionResp{
Total: total,
Versions: datautil.Slice(res, o.db2pbApplication),
}, nil
}

func putUpdate[T any](update map[string]any, name string, val interface{ GetValuePtr() *T }) {
ptrVal := val.GetValuePtr()
if ptrVal == nil {
return
}
update[name] = *ptrVal
}
32 changes: 32 additions & 0 deletions pkg/common/db/database/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package database

import (
"context"
"go.mongodb.org/mongo-driver/bson/primitive"
"time"

"github.com/openimsdk/chat/pkg/common/db/cache"
Expand Down Expand Up @@ -78,6 +79,11 @@ type AdminDatabaseInterface interface {
CacheToken(ctx context.Context, userID string, token string, expire time.Duration) error
GetTokens(ctx context.Context, userID string) (map[string]int32, error)
DeleteToken(ctx context.Context, userID string) error
LatestVersion(ctx context.Context, platform string) (*admindb.Application, error)
AddVersion(ctx context.Context, val *admindb.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, []*admindb.Application, error)
}

func NewAdminDatabase(cli *mongoutil.Client, rdb redis.UniversalClient) (AdminDatabaseInterface, error) {
Expand Down Expand Up @@ -117,6 +123,10 @@ func NewAdminDatabase(cli *mongoutil.Client, rdb redis.UniversalClient) (AdminDa
if err != nil {
return nil, err
}
application, err := admin.NewApplication(cli.GetDB())
if err != nil {
return nil, err
}
return &AdminDatabase{
tx: cli.GetTx(),
admin: a,
Expand All @@ -128,6 +138,7 @@ func NewAdminDatabase(cli *mongoutil.Client, rdb redis.UniversalClient) (AdminDa
registerAddGroup: registerAddGroup,
applet: applet,
clientConfig: clientConfig,
application: application,
cache: cache.NewTokenInterface(rdb),
}, nil
}
Expand All @@ -143,6 +154,7 @@ type AdminDatabase struct {
registerAddGroup admindb.RegisterAddGroupInterface
applet admindb.AppletInterface
clientConfig admindb.ClientConfigInterface
application admindb.ApplicationInterface
cache cache.TokenInterface
}

Expand Down Expand Up @@ -347,3 +359,23 @@ func (o *AdminDatabase) GetTokens(ctx context.Context, userID string) (map[strin
func (o *AdminDatabase) DeleteToken(ctx context.Context, userID string) error {
return o.cache.DeleteTokenByUid(ctx, userID)
}

func (o *AdminDatabase) LatestVersion(ctx context.Context, platform string) (*admindb.Application, error) {
return o.application.LatestVersion(ctx, platform)
}

func (o *AdminDatabase) AddVersion(ctx context.Context, val *admindb.Application) error {
return o.application.AddVersion(ctx, val)
}

func (o *AdminDatabase) UpdateVersion(ctx context.Context, id primitive.ObjectID, update map[string]any) error {
return o.application.UpdateVersion(ctx, id, update)
}

func (o *AdminDatabase) DeleteVersion(ctx context.Context, id []primitive.ObjectID) error {
return o.application.DeleteVersion(ctx, id)
}

func (o *AdminDatabase) PageVersion(ctx context.Context, platforms []string, page pagination.Pagination) (int64, []*admindb.Application, error) {
return o.application.PageVersion(ctx, platforms, page)
}
83 changes: 83 additions & 0 deletions pkg/common/db/model/admin/application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package admin

import (
"context"
"github.com/openimsdk/chat/pkg/common/db/table/admin"
admindb "github.com/openimsdk/chat/pkg/common/db/table/admin"
"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 NewApplication(db *mongo.Database) (admindb.ApplicationInterface, error) {
coll := db.Collection("application")
_, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{
{
Keys: bson.D{
{Key: "platform", Value: 1},
{Key: "version", 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) (*admin.Application, error) {
return mongoutil.FindOne[*admin.Application](ctx, a.coll, bson.M{"platform": platform}, options.FindOne().SetSort(a.sort()))
}

func (a *ApplicationMgo) AddVersion(ctx context.Context, val *admin.Application) error {
if val.ID.IsZero() {
val.ID = primitive.NewObjectID()
}
return mongoutil.InsertMany(ctx, a.coll, []*admin.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, []*admin.Application, error) {
filter := bson.M{}
if len(platforms) > 0 {
filter["platform"] = bson.M{"$in": platforms}
}
return mongoutil.FindPage[*admin.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}))
}
29 changes: 29 additions & 0 deletions pkg/common/db/table/admin/application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package admin

import (
"context"
"github.com/openimsdk/tools/db/pagination"
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)

type Application struct {
ID primitive.ObjectID `bson:"_id"`
Platform string `bson:"platform"`
Hot bool `bson:"hot"`
Version string `bson:"version"`
Url string `bson:"url"`
Text string `bson:"text"`
Force bool `bson:"force"`
Latest bool `bson:"latest"`
CreateTime time.Time `bson:"create_time"`
}

type ApplicationInterface interface {
LatestVersion(ctx context.Context, platform string) (*Application, error)
AddVersion(ctx context.Context, val *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, []*Application, error)
FindPlatform(ctx context.Context, id []primitive.ObjectID) ([]string, error)
}
Loading
Loading