mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-04-06 04:15:46 +08:00
optimization: change the configuration file from being read globally … (#1935)
* optimization: change the configuration file from being read globally to being read independently. * optimization: change the configuration file from being read globally to being read independently. * optimization: change the configuration file from being read globally to being read independently. * optimization: config file changed to dependency injection. * fix: replace global config with dependency injection * fix: replace global config with dependency injection * fix: import the enough param * fix: import the enough param * fix: import the enough param * fix: fix the component check of path * fix: fix the kafka of tls is nil problem * fix: fix the TLS.CACrt is nil error * fix: fix the valiable shadows problem * fix: fix the comflect * optimization: message remove options. * fix: fix the param pass error * fix: find error * fix: find error * fix: find eror * fix: find error * fix: find error * fix: del the undifined func * fix: find error * fix: fix the error * fix: pass config * fix: find error * fix: find error * fix: find error * fix: find error * fix: find error * fix: fix the config * fix: fix the error * fix: fix the config pass error * fix: fix the eror * fix: fix the error * fix: fix the error * fix: fix the error * fix: find error * fix: fix the error * fix: fix the config * fix: add return err * fix: fix the err2 * fix: err * fix: fix the func * fix: del the chinese comment * fix: fix the func * fix: fix the gateway_test logic * fix: s3 * test * test * fix: not found --------- Co-authored-by: luhaoling <2198702716@qq.com> Co-authored-by: withchao <993506633@qq.com>
This commit is contained in:
parent
efb8310531
commit
383758782e
@ -15,115 +15,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
_ "net/http/pprof"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"strconv"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/api"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
|
||||||
ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
|
_ "net/http/pprof"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
apiCmd := cmd.NewApiCmd()
|
apiCmd := cmd.NewApiCmd()
|
||||||
apiCmd.AddPortFlag()
|
apiCmd.AddPortFlag()
|
||||||
apiCmd.AddPrometheusPortFlag()
|
apiCmd.AddPrometheusPortFlag()
|
||||||
apiCmd.AddApi(run)
|
|
||||||
if err := apiCmd.Execute(); err != nil {
|
if err := apiCmd.Execute(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(port int, proPort int) error {
|
|
||||||
if port == 0 || proPort == 0 {
|
|
||||||
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
|
|
||||||
return errs.Wrap(fmt.Errorf(err))
|
|
||||||
}
|
|
||||||
rdb, err := cache.NewRedis()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var client discoveryregistry.SvcDiscoveryRegistry
|
|
||||||
|
|
||||||
// Determine whether zk is passed according to whether it is a clustered deployment
|
|
||||||
client, err = kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.Config.EncodeConfig()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
netDone = make(chan struct{}, 1)
|
|
||||||
netErr error
|
|
||||||
)
|
|
||||||
|
|
||||||
router := api.NewGinRouter(client, rdb)
|
|
||||||
if config.Config.Prometheus.Enable {
|
|
||||||
go func() {
|
|
||||||
p := ginprom.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
|
|
||||||
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
|
|
||||||
if err = p.Use(router); err != nil && err != http.ErrServerClosed {
|
|
||||||
netErr = errs.Wrap(err, fmt.Sprintf("prometheus start err: %d", proPort))
|
|
||||||
netDone <- struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
var address string
|
|
||||||
if config.Config.Api.ListenIP != "" {
|
|
||||||
address = net.JoinHostPort(config.Config.Api.ListenIP, strconv.Itoa(port))
|
|
||||||
} else {
|
|
||||||
address = net.JoinHostPort("0.0.0.0", strconv.Itoa(port))
|
|
||||||
}
|
|
||||||
|
|
||||||
server := http.Server{Addr: address, Handler: router}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
err = server.ListenAndServe()
|
|
||||||
if err != nil && err != http.ErrServerClosed {
|
|
||||||
netErr = errs.Wrap(err, fmt.Sprintf("api start err: %s", server.Addr))
|
|
||||||
netDone <- struct{}{}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
sigs := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigs, syscall.SIGTERM)
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
select {
|
|
||||||
case <-sigs:
|
|
||||||
util.SIGTERMExit()
|
|
||||||
err := server.Shutdown(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "api shutdown err")
|
|
||||||
}
|
|
||||||
case <-netDone:
|
|
||||||
close(netDone)
|
|
||||||
return netErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@ -15,14 +15,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/tools"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cronTaskCmd := cmd.NewCronTaskCmd()
|
cronTaskCmd := cmd.NewCronTaskCmd()
|
||||||
if err := cronTaskCmd.Exec(tools.StartTask); err != nil {
|
if err := cronTaskCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ func main() {
|
|||||||
msgGatewayCmd.AddWsPortFlag()
|
msgGatewayCmd.AddWsPortFlag()
|
||||||
msgGatewayCmd.AddPortFlag()
|
msgGatewayCmd.AddPortFlag()
|
||||||
msgGatewayCmd.AddPrometheusPortFlag()
|
msgGatewayCmd.AddPrometheusPortFlag()
|
||||||
|
|
||||||
if err := msgGatewayCmd.Exec(); err != nil {
|
if err := msgGatewayCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push"
|
"github.com/openimsdk/open-im-server/v3/internal/push"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
pushCmd := cmd.NewRpcCmd(cmd.RpcPushServer)
|
pushCmd := cmd.NewRpcCmd(cmd.RpcPushServer, push.Start)
|
||||||
pushCmd.AddPortFlag()
|
pushCmd.AddPortFlag()
|
||||||
pushCmd.AddPrometheusPortFlag()
|
pushCmd.AddPrometheusPortFlag()
|
||||||
if err := pushCmd.Exec(); err != nil {
|
if err := pushCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := pushCmd.StartSvr(config.Config.RpcRegisterName.OpenImPushName, push.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/auth"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
authCmd := cmd.NewRpcCmd(cmd.RpcAuthServer)
|
authCmd := cmd.NewRpcCmd(cmd.RpcAuthServer, auth.Start)
|
||||||
authCmd.AddPortFlag()
|
authCmd.AddPortFlag()
|
||||||
authCmd.AddPrometheusPortFlag()
|
authCmd.AddPrometheusPortFlag()
|
||||||
if err := authCmd.Exec(); err != nil {
|
if err := authCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := authCmd.StartSvr(config.Config.RpcRegisterName.OpenImAuthName, auth.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/conversation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcConversationServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcConversationServer, conversation.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImConversationName, conversation.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/friend"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcFriendServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcFriendServer, friend.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImFriendName, friend.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/group"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcGroupServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcGroupServer, group.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImGroupName, group.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/msg"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcMsgServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcMsgServer, msg.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImMsgName, msg.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/third"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcThirdServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcThirdServer, third.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImThirdName, third.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
|
"github.com/openimsdk/open-im-server/v3/internal/rpc/user"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/cmd"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rpcCmd := cmd.NewRpcCmd(cmd.RpcUserServer)
|
rpcCmd := cmd.NewRpcCmd(cmd.RpcUserServer, user.Start)
|
||||||
rpcCmd.AddPortFlag()
|
rpcCmd.AddPortFlag()
|
||||||
rpcCmd.AddPrometheusPortFlag()
|
rpcCmd.AddPrometheusPortFlag()
|
||||||
if err := rpcCmd.Exec(); err != nil {
|
if err := rpcCmd.Exec(); err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
if err := rpcCmd.StartSvr(config.Config.RpcRegisterName.OpenImUserName, user.Start); err != nil {
|
|
||||||
util.ExitWithError(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the user has the app manager role.
|
// Check if the user has the app manager role.
|
||||||
if !authverify.IsAppManagerUid(c) {
|
if !authverify.IsAppManagerUid(c, m.Config) {
|
||||||
// Respond with a permission error if the user is not an app manager.
|
// Respond with a permission error if the user is not an app manager.
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
@ -256,7 +256,7 @@ func (m *MessageApi) SendBusinessNotification(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !authverify.IsAppManagerUid(c) {
|
if !authverify.IsAppManagerUid(c, m.Config) {
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.ZInfo(c, "BatchSendMsg", "req", req)
|
log.ZInfo(c, "BatchSendMsg", "req", req)
|
||||||
if err := authverify.CheckAdmin(c); err != nil {
|
if err := authverify.CheckAdmin(c, m.Config); err != nil {
|
||||||
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -17,53 +17,142 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||||
|
ginprom "github.com/openimsdk/open-im-server/v3/pkg/common/ginprometheus"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/apiresp"
|
"github.com/OpenIMSDK/tools/apiresp"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/OpenIMSDK/tools/mw"
|
|
||||||
"github.com/OpenIMSDK/tools/tokenverify"
|
"github.com/OpenIMSDK/tools/tokenverify"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
|
func Start(config *config.GlobalConfig, port int, proPort int) error {
|
||||||
discov.AddOption(
|
log.ZDebug(context.Background(), "configAPI1111111111111111111", config, "port", port, "javafdasfs")
|
||||||
mw.GrpcClient(),
|
if port == 0 || proPort == 0 {
|
||||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
err := "port or proPort is empty:" + strconv.Itoa(port) + "," + strconv.Itoa(proPort)
|
||||||
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")),
|
return errs.Wrap(fmt.Errorf(err))
|
||||||
) // Default RPC middleware
|
}
|
||||||
|
rdb, err := cache.NewRedis(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var client discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
|
||||||
|
// Determine whether zk is passed according to whether it is a clustered deployment
|
||||||
|
client, err = kdisc.NewDiscoveryRegister(config)
|
||||||
|
if err != nil {
|
||||||
|
return errs.Wrap(err, "register discovery err")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||||
|
return errs.Wrap(err, "create rpc root nodes error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = client.RegisterConf2Registry(constant.OpenIMCommonConfigKey, config.EncodeConfig()); err != nil {
|
||||||
|
return errs.Wrap(err)
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
netDone = make(chan struct{}, 1)
|
||||||
|
netErr error
|
||||||
|
)
|
||||||
|
router := newGinRouter(client, rdb, config)
|
||||||
|
if config.Prometheus.Enable {
|
||||||
|
go func() {
|
||||||
|
p := ginprom.NewPrometheus("app", prommetrics.GetGinCusMetrics("Api"))
|
||||||
|
p.SetListenAddress(fmt.Sprintf(":%d", proPort))
|
||||||
|
if err = p.Use(router); err != nil && err != http.ErrServerClosed {
|
||||||
|
netErr = errs.Wrap(err, fmt.Sprintf("prometheus start err: %d", proPort))
|
||||||
|
netDone <- struct{}{}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var address string
|
||||||
|
if config.Api.ListenIP != "" {
|
||||||
|
address = net.JoinHostPort(config.Api.ListenIP, strconv.Itoa(port))
|
||||||
|
} else {
|
||||||
|
address = net.JoinHostPort("0.0.0.0", strconv.Itoa(port))
|
||||||
|
}
|
||||||
|
|
||||||
|
server := http.Server{Addr: address, Handler: router}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
err = server.ListenAndServe()
|
||||||
|
if err != nil && err != http.ErrServerClosed {
|
||||||
|
netErr = errs.Wrap(err, fmt.Sprintf("api start err: %s", server.Addr))
|
||||||
|
netDone <- struct{}{}
|
||||||
|
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
sigs := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigs, syscall.SIGTERM)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
select {
|
||||||
|
case <-sigs:
|
||||||
|
util.SIGTERMExit()
|
||||||
|
err := server.Shutdown(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return errs.Wrap(err, "shutdown err")
|
||||||
|
}
|
||||||
|
case <-netDone:
|
||||||
|
close(netDone)
|
||||||
|
return netErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGinRouter(disCov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient, config *config.GlobalConfig) *gin.Engine {
|
||||||
|
disCov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||||
_ = v.RegisterValidation("required_if", RequiredIf)
|
_ = v.RegisterValidation("required_if", RequiredIf)
|
||||||
}
|
}
|
||||||
log.ZInfo(context.Background(), "load config", "config", config.Config)
|
|
||||||
r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
|
r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
|
||||||
// init rpc client here
|
// init rpc client here
|
||||||
userRpc := rpcclient.NewUser(discov)
|
userRpc := rpcclient.NewUser(disCov, config)
|
||||||
groupRpc := rpcclient.NewGroup(discov)
|
groupRpc := rpcclient.NewGroup(disCov, config)
|
||||||
friendRpc := rpcclient.NewFriend(discov)
|
friendRpc := rpcclient.NewFriend(disCov, config)
|
||||||
messageRpc := rpcclient.NewMessage(discov)
|
messageRpc := rpcclient.NewMessage(disCov, config)
|
||||||
conversationRpc := rpcclient.NewConversation(discov)
|
conversationRpc := rpcclient.NewConversation(disCov, config)
|
||||||
authRpc := rpcclient.NewAuth(discov)
|
authRpc := rpcclient.NewAuth(disCov, config)
|
||||||
thirdRpc := rpcclient.NewThird(discov)
|
thirdRpc := rpcclient.NewThird(disCov, config)
|
||||||
|
|
||||||
u := NewUserApi(*userRpc)
|
u := NewUserApi(*userRpc)
|
||||||
m := NewMessageApi(messageRpc, userRpc)
|
m := NewMessageApi(messageRpc, userRpc)
|
||||||
ParseToken := GinParseToken(rdb)
|
ParseToken := GinParseToken(rdb, config)
|
||||||
userRouterGroup := r.Group("/user")
|
userRouterGroup := r.Group("/user")
|
||||||
{
|
{
|
||||||
userRouterGroup.POST("/user_register", u.UserRegister)
|
userRouterGroup.POST("/user_register", u.UserRegister)
|
||||||
@ -157,8 +246,8 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
// Third service
|
// Third service
|
||||||
thirdGroup := r.Group("/third", ParseToken)
|
thirdGroup := r.Group("/third", ParseToken)
|
||||||
{
|
{
|
||||||
thirdGroup.GET("/prometheus", GetPrometheus)
|
|
||||||
t := NewThirdApi(*thirdRpc)
|
t := NewThirdApi(*thirdRpc)
|
||||||
|
thirdGroup.GET("/prometheus", t.GetPrometheus)
|
||||||
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
|
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
|
||||||
thirdGroup.POST("/set_app_badge", t.SetAppBadge)
|
thirdGroup.POST("/set_app_badge", t.SetAppBadge)
|
||||||
|
|
||||||
@ -225,12 +314,12 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// GinParseToken is a middleware that parses the token in the request header and verifies it.
|
func GinParseToken(rdb redis.UniversalClient, config *config.GlobalConfig) gin.HandlerFunc {
|
||||||
func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|
||||||
dataBase := controller.NewAuthDatabase(
|
dataBase := controller.NewAuthDatabase(
|
||||||
cache.NewMsgCacheModel(rdb),
|
cache.NewMsgCacheModel(rdb, config),
|
||||||
config.Config.Secret,
|
config.Secret,
|
||||||
config.Config.TokenPolicy.Expire,
|
config.TokenPolicy.Expire,
|
||||||
|
config,
|
||||||
)
|
)
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
switch c.Request.Method {
|
switch c.Request.Method {
|
||||||
@ -242,7 +331,7 @@ func GinParseToken(rdb redis.UniversalClient) gin.HandlerFunc {
|
|||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret())
|
claims, err := tokenverify.GetClaimFromToken(token, authverify.Secret(config.Secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(c, "jwt get token error", errs.ErrTokenUnknown.Wrap())
|
log.ZWarn(c, "jwt get token error", errs.ErrTokenUnknown.Wrap())
|
||||||
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
apiresp.GinError(c, errs.ErrTokenUnknown.Wrap())
|
||||||
|
@ -19,12 +19,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/a2r"
|
"github.com/OpenIMSDK/tools/a2r"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -126,6 +126,6 @@ func (o *ThirdApi) SearchLogs(c *gin.Context) {
|
|||||||
a2r.Call(third.ThirdClient.SearchLogs, o.Client, c)
|
a2r.Call(third.ThirdClient.SearchLogs, o.Client, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPrometheus(c *gin.Context) {
|
func (o *ThirdApi) GetPrometheus(c *gin.Context) {
|
||||||
c.Redirect(http.StatusFound, config2.Config.Prometheus.GrafanaUrl)
|
c.Redirect(http.StatusFound, o.Config.Prometheus.GrafanaUrl)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
|
|||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := u.Discov.GetConns(c, u.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
@ -134,7 +134,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
|
|||||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conns, err := u.Discov.GetConns(c, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := u.Discov.GetConns(c, u.Config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
apiresp.GinError(c, err)
|
apiresp.GinError(c, err)
|
||||||
return
|
return
|
||||||
|
@ -25,12 +25,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func callBackURL() string {
|
func CallbackUserOnline(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int, isAppBackground bool, connID string) error {
|
||||||
return config.Config.Callback.CallbackUrl
|
if !globalConfig.Callback.CallbackUserOnline.Enable {
|
||||||
}
|
|
||||||
|
|
||||||
func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAppBackground bool, connID string) error {
|
|
||||||
if !config.Config.Callback.CallbackUserOnline.Enable {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := cbapi.CallbackUserOnlineReq{
|
req := cbapi.CallbackUserOnlineReq{
|
||||||
@ -48,14 +44,14 @@ func CallbackUserOnline(ctx context.Context, userID string, platformID int, isAp
|
|||||||
ConnID: connID,
|
ConnID: connID,
|
||||||
}
|
}
|
||||||
resp := cbapi.CommonCallbackResp{}
|
resp := cbapi.CommonCallbackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), &req, &resp, config.Config.Callback.CallbackUserOnline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, &req, &resp, globalConfig.Callback.CallbackUserOnline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackUserOffline(ctx context.Context, userID string, platformID int, connID string) error {
|
func CallbackUserOffline(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int, connID string) error {
|
||||||
if !config.Config.Callback.CallbackUserOffline.Enable {
|
if !globalConfig.Callback.CallbackUserOffline.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackUserOfflineReq{
|
req := &cbapi.CallbackUserOfflineReq{
|
||||||
@ -72,14 +68,14 @@ func CallbackUserOffline(ctx context.Context, userID string, platformID int, con
|
|||||||
ConnID: connID,
|
ConnID: connID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackUserOfflineResp{}
|
resp := &cbapi.CallbackUserOfflineResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackUserOffline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackUserKickOff(ctx context.Context, userID string, platformID int) error {
|
func CallbackUserKickOff(ctx context.Context, globalConfig *config.GlobalConfig, userID string, platformID int) error {
|
||||||
if !config.Config.Callback.CallbackUserKickOff.Enable {
|
if !globalConfig.Callback.CallbackUserKickOff.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackUserKickOffReq{
|
req := &cbapi.CallbackUserKickOffReq{
|
||||||
@ -95,7 +91,7 @@ func CallbackUserKickOff(ctx context.Context, userID string, platformID int) err
|
|||||||
Seq: time.Now().UnixMilli(),
|
Seq: time.Now().UnixMilli(),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CommonCallbackResp{}
|
resp := &cbapi.CommonCallbackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, callBackURL(), req, resp, config.Config.Callback.CallbackUserOffline); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackUserOffline); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -31,24 +31,25 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) InitServer(disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func (s *Server) InitServer(config *config.GlobalConfig, disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msgModel := cache.NewMsgCacheModel(rdb)
|
msgModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
s.LongConnServer.SetDiscoveryRegistry(disCov)
|
s.LongConnServer.SetDiscoveryRegistry(disCov, config)
|
||||||
s.LongConnServer.SetCacheHandler(msgModel)
|
s.LongConnServer.SetCacheHandler(msgModel)
|
||||||
msggateway.RegisterMsgGatewayServer(server, s)
|
msggateway.RegisterMsgGatewayServer(server, s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start(conf *config.GlobalConfig) error {
|
||||||
return startrpc.Start(
|
return startrpc.Start(
|
||||||
s.rpcPort,
|
s.rpcPort,
|
||||||
config.Config.RpcRegisterName.OpenImMessageGatewayName,
|
conf.RpcRegisterName.OpenImMessageGatewayName,
|
||||||
s.prometheusPort,
|
s.prometheusPort,
|
||||||
|
conf,
|
||||||
s.InitServer,
|
s.InitServer,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -58,18 +59,20 @@ type Server struct {
|
|||||||
prometheusPort int
|
prometheusPort int
|
||||||
LongConnServer LongConnServer
|
LongConnServer LongConnServer
|
||||||
pushTerminal []int
|
pushTerminal []int
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
func (s *Server) SetLongConnServer(LongConnServer LongConnServer) {
|
||||||
s.LongConnServer = LongConnServer
|
s.LongConnServer = LongConnServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(rpcPort int, proPort int, longConnServer LongConnServer) *Server {
|
func NewServer(rpcPort int, proPort int, longConnServer LongConnServer, config *config.GlobalConfig) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
rpcPort: rpcPort,
|
rpcPort: rpcPort,
|
||||||
prometheusPort: proPort,
|
prometheusPort: proPort,
|
||||||
LongConnServer: longConnServer,
|
LongConnServer: longConnServer,
|
||||||
pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID},
|
pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID},
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +87,7 @@ func (s *Server) GetUsersOnlineStatus(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msggateway.GetUsersOnlineStatusReq,
|
req *msggateway.GetUsersOnlineStatusReq,
|
||||||
) (*msggateway.GetUsersOnlineStatusResp, error) {
|
) (*msggateway.GetUsersOnlineStatusResp, error) {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("only app manager")
|
return nil, errs.ErrNoPermission.Wrap("only app manager")
|
||||||
}
|
}
|
||||||
var resp msggateway.GetUsersOnlineStatusResp
|
var resp msggateway.GetUsersOnlineStatusResp
|
||||||
|
@ -22,23 +22,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// RunWsAndServer run ws server.
|
// RunWsAndServer run ws server.
|
||||||
func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
|
func RunWsAndServer(conf *config.GlobalConfig, rpcPort, wsPort, prometheusPort int) error {
|
||||||
fmt.Println("start rpc/msg_gateway server, port: ", rpcPort, wsPort, prometheusPort, ", OpenIM version: ", config.Version)
|
fmt.Println("start rpc/msg_gateway server, port: ", rpcPort, wsPort, prometheusPort, ", OpenIM version: ", config.Version)
|
||||||
longServer, err := NewWsServer(
|
longServer, err := NewWsServer(
|
||||||
|
conf,
|
||||||
WithPort(wsPort),
|
WithPort(wsPort),
|
||||||
WithMaxConnNum(int64(config.Config.LongConnSvr.WebsocketMaxConnNum)),
|
WithMaxConnNum(int64(conf.LongConnSvr.WebsocketMaxConnNum)),
|
||||||
WithHandshakeTimeout(time.Duration(config.Config.LongConnSvr.WebsocketTimeout)*time.Second),
|
WithHandshakeTimeout(time.Duration(conf.LongConnSvr.WebsocketTimeout)*time.Second),
|
||||||
WithMessageMaxMsgLength(config.Config.LongConnSvr.WebsocketMaxMsgLen),
|
WithMessageMaxMsgLength(conf.LongConnSvr.WebsocketMaxMsgLen),
|
||||||
WithWriteBufferSize(config.Config.LongConnSvr.WebsocketWriteBufferSize),
|
WithWriteBufferSize(conf.LongConnSvr.WebsocketWriteBufferSize),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hubServer := NewServer(rpcPort, prometheusPort, longServer)
|
hubServer := NewServer(rpcPort, prometheusPort, longServer, conf)
|
||||||
netDone := make(chan error)
|
netDone := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
err = hubServer.Start()
|
err = hubServer.Start(conf)
|
||||||
netDone <- err
|
netDone <- err
|
||||||
}()
|
}()
|
||||||
return hubServer.LongConnServer.Run(netDone)
|
return hubServer.LongConnServer.Run(netDone)
|
||||||
|
@ -16,6 +16,7 @@ package msggateway
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
@ -105,9 +106,9 @@ type GrpcHandler struct {
|
|||||||
validate *validator.Validate
|
validate *validator.Validate
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry) *GrpcHandler {
|
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) *GrpcHandler {
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
pushRpcClient := rpcclient.NewPushRpcClient(client)
|
pushRpcClient := rpcclient.NewPushRpcClient(client, config)
|
||||||
return &GrpcHandler{
|
return &GrpcHandler{
|
||||||
msgRpcClient: &msgRpcClient,
|
msgRpcClient: &msgRpcClient,
|
||||||
pushClient: &pushRpcClient, validate: validate,
|
pushClient: &pushRpcClient, validate: validate,
|
||||||
|
@ -49,7 +49,7 @@ type LongConnServer interface {
|
|||||||
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
|
||||||
Validate(s any) error
|
Validate(s any) error
|
||||||
SetCacheHandler(cache cache.MsgModel)
|
SetCacheHandler(cache cache.MsgModel)
|
||||||
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry)
|
SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig)
|
||||||
KickUserConn(client *Client) error
|
KickUserConn(client *Client) error
|
||||||
UnRegister(c *Client)
|
UnRegister(c *Client)
|
||||||
SetKickHandlerInfo(i *kickHandler)
|
SetKickHandlerInfo(i *kickHandler)
|
||||||
@ -66,6 +66,7 @@ type LongConnServer interface {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
type WsServer struct {
|
type WsServer struct {
|
||||||
|
globalConfig *config.GlobalConfig
|
||||||
port int
|
port int
|
||||||
wsMaxConnNum int64
|
wsMaxConnNum int64
|
||||||
registerChan chan *Client
|
registerChan chan *Client
|
||||||
@ -92,9 +93,9 @@ type kickHandler struct {
|
|||||||
newClient *Client
|
newClient *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) SetDiscoveryRegistry(disCov discoveryregistry.SvcDiscoveryRegistry) {
|
func (ws *WsServer) SetDiscoveryRegistry(disCov discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) {
|
||||||
ws.MessageHandler = NewGrpcHandler(ws.validate, disCov)
|
ws.MessageHandler = NewGrpcHandler(ws.validate, disCov, config)
|
||||||
u := rpcclient.NewUserRpcClient(disCov)
|
u := rpcclient.NewUserRpcClient(disCov, config)
|
||||||
ws.userClient = &u
|
ws.userClient = &u
|
||||||
ws.disCov = disCov
|
ws.disCov = disCov
|
||||||
}
|
}
|
||||||
@ -106,12 +107,12 @@ func (ws *WsServer) SetUserOnlineStatus(ctx context.Context, client *Client, sta
|
|||||||
}
|
}
|
||||||
switch status {
|
switch status {
|
||||||
case constant.Online:
|
case constant.Online:
|
||||||
err := CallbackUserOnline(ctx, client.UserID, client.PlatformID, client.IsBackground, client.ctx.GetConnID())
|
err := CallbackUserOnline(ctx, ws.globalConfig, client.UserID, client.PlatformID, client.IsBackground, client.ctx.GetConnID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackUserOnline err", err)
|
log.ZWarn(ctx, "CallbackUserOnline err", err)
|
||||||
}
|
}
|
||||||
case constant.Offline:
|
case constant.Offline:
|
||||||
err := CallbackUserOffline(ctx, client.UserID, client.PlatformID, client.ctx.GetConnID())
|
err := CallbackUserOffline(ctx, ws.globalConfig, client.UserID, client.PlatformID, client.ctx.GetConnID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackUserOffline err", err)
|
log.ZWarn(ctx, "CallbackUserOffline err", err)
|
||||||
}
|
}
|
||||||
@ -141,13 +142,14 @@ func (ws *WsServer) GetUserPlatformCons(userID string, platform int) ([]*Client,
|
|||||||
return ws.clients.Get(userID, platform)
|
return ws.clients.Get(userID, platform)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWsServer(opts ...Option) (*WsServer, error) {
|
func NewWsServer(globalConfig *config.GlobalConfig, opts ...Option) (*WsServer, error) {
|
||||||
var config configs
|
var config configs
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&config)
|
o(&config)
|
||||||
}
|
}
|
||||||
v := validator.New()
|
v := validator.New()
|
||||||
return &WsServer{
|
return &WsServer{
|
||||||
|
globalConfig: globalConfig,
|
||||||
port: config.port,
|
port: config.port,
|
||||||
wsMaxConnNum: config.maxConnNum,
|
wsMaxConnNum: config.maxConnNum,
|
||||||
writeBufferSize: config.writeBufferSize,
|
writeBufferSize: config.writeBufferSize,
|
||||||
@ -221,7 +223,7 @@ func (ws *WsServer) Run(done chan error) error {
|
|||||||
var concurrentRequest = 3
|
var concurrentRequest = 3
|
||||||
|
|
||||||
func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *Client) error {
|
func (ws *WsServer) sendUserOnlineInfoToOtherNode(ctx context.Context, client *Client) error {
|
||||||
conns, err := ws.disCov.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := ws.disCov.GetConns(ctx, ws.globalConfig.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -286,7 +288,7 @@ func (ws *WsServer) registerClient(client *Client) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
if config.Config.Envs.Discovery == "zookeeper" {
|
if ws.globalConfig.Envs.Discovery == "zookeeper" {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
@ -329,7 +331,7 @@ func (ws *WsServer) KickUserConn(client *Client) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
func (ws *WsServer) multiTerminalLoginChecker(clientOK bool, oldClients []*Client, newClient *Client) {
|
||||||
switch config.Config.MultiLoginPolicy {
|
switch ws.globalConfig.MultiLoginPolicy {
|
||||||
case constant.DefalutNotKick:
|
case constant.DefalutNotKick:
|
||||||
case constant.PCAndOther:
|
case constant.PCAndOther:
|
||||||
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
if constant.PlatformIDToClass(newClient.PlatformID) == constant.TerminalPC {
|
||||||
@ -441,7 +443,7 @@ func (ws *WsServer) ParseWSArgs(r *http.Request) (args *WSArgs, err error) {
|
|||||||
return nil, errs.ErrConnArgsErr.Wrap("platformID is not int")
|
return nil, errs.ErrConnArgsErr.Wrap("platformID is not int")
|
||||||
}
|
}
|
||||||
v.PlatformID = platformID
|
v.PlatformID = platformID
|
||||||
if err = authverify.WsVerifyToken(v.Token, v.UserID, platformID); err != nil {
|
if err = authverify.WsVerifyToken(v.Token, v.UserID, ws.globalConfig.Secret, platformID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if query.Get(Compression) == GzipCompressionProtocol {
|
if query.Get(Compression) == GzipCompressionProtocol {
|
||||||
|
@ -44,21 +44,22 @@ type MsgTransfer struct {
|
|||||||
// This consumer aggregated messages, subscribed to the topic:ws2ms_chat,
|
// This consumer aggregated messages, subscribed to the topic:ws2ms_chat,
|
||||||
// the modification notification is sent to msg_to_modify topic, the message is stored in redis, Incr Redis,
|
// the modification notification is sent to msg_to_modify topic, the message is stored in redis, Incr Redis,
|
||||||
// and then the message is sent to ms2pschat topic for push, and the message is sent to msg_to_mongo topic for persistence
|
// and then the message is sent to ms2pschat topic for push, and the message is sent to msg_to_mongo topic for persistence
|
||||||
historyCH *OnlineHistoryRedisConsumerHandler
|
historyCH *OnlineHistoryRedisConsumerHandler
|
||||||
|
historyMongoCH *OnlineHistoryMongoConsumerHandler
|
||||||
// mongoDB batch insert, delete messages in redis after success,
|
// mongoDB batch insert, delete messages in redis after success,
|
||||||
// and handle the deletion notification message deleted subscriptions topic: msg_to_mongo
|
// and handle the deletion notification message deleted subscriptions topic: msg_to_mongo
|
||||||
historyMongoCH *OnlineHistoryMongoConsumerHandler
|
ctx context.Context
|
||||||
ctx context.Context
|
cancel context.CancelFunc
|
||||||
cancel context.CancelFunc
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartTransfer(prometheusPort int) error {
|
func StartTransfer(config *config.GlobalConfig, prometheusPort int) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -66,38 +67,37 @@ func StartTransfer(prometheusPort int) error {
|
|||||||
if err = mongo.CreateMsgIndex(); err != nil {
|
if err = mongo.CreateMsgIndex(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
client, err := kdisc.NewDiscoveryRegister(config)
|
||||||
client, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := client.CreateRpcRootNodes(config.Config.GetServiceNames()); err != nil {
|
if err := client.CreateRpcRootNodes(config.GetServiceNames()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
msgModel := cache.NewMsgCacheModel(rdb)
|
msgModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
|
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, msgModel, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgTransfer, err := NewMsgTransfer(msgDatabase, &conversationRpcClient, &groupRpcClient)
|
msgTransfer, err := NewMsgTransfer(config, msgDatabase, &conversationRpcClient, &groupRpcClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return msgTransfer.Start(prometheusPort)
|
return msgTransfer.Start(prometheusPort, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) (*MsgTransfer, error) {
|
func NewMsgTransfer(config *config.GlobalConfig, msgDatabase controller.CommonMsgDatabase, conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) (*MsgTransfer, error) {
|
||||||
historyCH, err := NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient)
|
historyCH, err := NewOnlineHistoryRedisConsumerHandler(config, msgDatabase, conversationRpcClient, groupRpcClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
historyMongoCH, err := NewOnlineHistoryMongoConsumerHandler(msgDatabase)
|
historyMongoCH, err := NewOnlineHistoryMongoConsumerHandler(config, msgDatabase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -105,11 +105,12 @@ func NewMsgTransfer(msgDatabase controller.CommonMsgDatabase, conversationRpcCli
|
|||||||
return &MsgTransfer{
|
return &MsgTransfer{
|
||||||
historyCH: historyCH,
|
historyCH: historyCH,
|
||||||
historyMongoCH: historyMongoCH,
|
historyMongoCH: historyMongoCH,
|
||||||
|
config: config,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransfer) Start(prometheusPort int) error {
|
func (m *MsgTransfer) Start(prometheusPort int, config *config.GlobalConfig) error {
|
||||||
fmt.Println("Start msg transfer", "prometheusPort:", prometheusPort)
|
fmt.Println("start msg transfer", "prometheusPort:", prometheusPort)
|
||||||
if prometheusPort <= 0 {
|
if prometheusPort <= 0 {
|
||||||
return errs.Wrap(errors.New("prometheusPort not correct"))
|
return errs.Wrap(errors.New("prometheusPort not correct"))
|
||||||
}
|
}
|
||||||
@ -123,13 +124,13 @@ func (m *MsgTransfer) Start(prometheusPort int) error {
|
|||||||
go m.historyCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyCH)
|
go m.historyCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyCH)
|
||||||
go m.historyMongoCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyMongoCH)
|
go m.historyMongoCH.historyConsumerGroup.RegisterHandleAndConsumer(m.ctx, m.historyMongoCH)
|
||||||
|
|
||||||
if config.Config.Prometheus.Enable {
|
if config.Prometheus.Enable {
|
||||||
go func() {
|
go func() {
|
||||||
proreg := prometheus.NewRegistry()
|
proreg := prometheus.NewRegistry()
|
||||||
proreg.MustRegister(
|
proreg.MustRegister(
|
||||||
collectors.NewGoCollector(),
|
collectors.NewGoCollector(),
|
||||||
)
|
)
|
||||||
proreg.MustRegister(prommetrics.GetGrpcCusMetrics("Transfer")...)
|
proreg.MustRegister(prommetrics.GetGrpcCusMetrics("Transfer", config)...)
|
||||||
http.Handle("/metrics", promhttp.HandlerFor(proreg, promhttp.HandlerOpts{Registry: proreg}))
|
http.Handle("/metrics", promhttp.HandlerFor(proreg, promhttp.HandlerOpts{Registry: proreg}))
|
||||||
err := http.ListenAndServe(fmt.Sprintf(":%d", prometheusPort), nil)
|
err := http.ListenAndServe(fmt.Sprintf(":%d", prometheusPort), nil)
|
||||||
if err != nil && err != http.ErrServerClosed {
|
if err != nil && err != http.ErrServerClosed {
|
||||||
|
@ -81,6 +81,7 @@ type OnlineHistoryRedisConsumerHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewOnlineHistoryRedisConsumerHandler(
|
func NewOnlineHistoryRedisConsumerHandler(
|
||||||
|
config *config.GlobalConfig,
|
||||||
database controller.CommonMsgDatabase,
|
database controller.CommonMsgDatabase,
|
||||||
conversationRpcClient *rpcclient.ConversationRpcClient,
|
conversationRpcClient *rpcclient.ConversationRpcClient,
|
||||||
groupRpcClient *rpcclient.GroupRpcClient,
|
groupRpcClient *rpcclient.GroupRpcClient,
|
||||||
@ -96,11 +97,29 @@ func NewOnlineHistoryRedisConsumerHandler(
|
|||||||
och.conversationRpcClient = conversationRpcClient
|
och.conversationRpcClient = conversationRpcClient
|
||||||
och.groupRpcClient = groupRpcClient
|
och.groupRpcClient = groupRpcClient
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
var tlsConfig *kafka.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kafka.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
och.historyConsumerGroup, err = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
|
och.historyConsumerGroup, err = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.LatestMsgToRedis.Topic},
|
||||||
|
config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToRedis,
|
||||||
|
tlsConfig,
|
||||||
|
)
|
||||||
// statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d
|
// statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d
|
||||||
// second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
|
// second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
|
||||||
return &och, err
|
return &och, err
|
||||||
|
@ -32,12 +32,28 @@ type OnlineHistoryMongoConsumerHandler struct {
|
|||||||
msgDatabase controller.CommonMsgDatabase
|
msgDatabase controller.CommonMsgDatabase
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) (*OnlineHistoryMongoConsumerHandler, error) {
|
func NewOnlineHistoryMongoConsumerHandler(config *config.GlobalConfig, database controller.CommonMsgDatabase) (*OnlineHistoryMongoConsumerHandler, error) {
|
||||||
|
var tlsConfig *kfk.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kfk.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
historyConsumerGroup, err := kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
historyConsumerGroup, err := kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.MsgToMongo.Topic},
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.MsgToMongo.Topic},
|
||||||
|
config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToMongo,
|
||||||
|
tlsConfig,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,14 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func url() string {
|
func callbackOfflinePush(
|
||||||
return config.Config.Callback.CallbackUrl
|
ctx context.Context,
|
||||||
}
|
config *config.GlobalConfig,
|
||||||
|
userIDs []string,
|
||||||
func callbackOfflinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData, offlinePushUserIDs *[]string) error {
|
msg *sdkws.MsgData,
|
||||||
if !config.Config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
offlinePushUserIDs *[]string,
|
||||||
|
) error {
|
||||||
|
if !config.Callback.CallbackOfflinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &callbackstruct.CallbackBeforePushReq{
|
req := &callbackstruct.CallbackBeforePushReq{
|
||||||
@ -55,7 +57,7 @@ func callbackOfflinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOfflinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackOfflinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,8 +70,8 @@ func callbackOfflinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func callbackOnlinePush(ctx context.Context, config *config.GlobalConfig, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
|
if !config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDs...) || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforePushReq{
|
req := callbackstruct.CallbackBeforePushReq{
|
||||||
@ -91,7 +93,7 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
|||||||
Content: GetContent(msg),
|
Content: GetContent(msg),
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, url(), req, resp, config.Config.Callback.CallbackOnlinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackOnlinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -99,11 +101,12 @@ func callbackOnlinePush(ctx context.Context, userIDs []string, msg *sdkws.MsgDat
|
|||||||
|
|
||||||
func callbackBeforeSuperGroupOnlinePush(
|
func callbackBeforeSuperGroupOnlinePush(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
config *config.GlobalConfig,
|
||||||
groupID string,
|
groupID string,
|
||||||
msg *sdkws.MsgData,
|
msg *sdkws.MsgData,
|
||||||
pushToUserIDs *[]string,
|
pushToUserIDs *[]string,
|
||||||
) error {
|
) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
if !config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable || msg.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||||
@ -123,7 +126,7 @@ func callbackBeforeSuperGroupOnlinePush(
|
|||||||
Seq: msg.Seq,
|
Seq: msg.Seq,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
if err := http.CallBackPostReturn(ctx, config.Callback.CallbackUrl, req, resp, config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ package push
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Consumer struct {
|
type Consumer struct {
|
||||||
@ -24,8 +25,8 @@ type Consumer struct {
|
|||||||
// successCount uint64
|
// successCount uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsumer(pusher *Pusher) (*Consumer, error) {
|
func NewConsumer(config *config.GlobalConfig, pusher *Pusher) (*Consumer, error) {
|
||||||
c, err := NewConsumerHandler(pusher)
|
c, err := NewConsumerHandler(config, pusher)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -36,5 +37,4 @@ func NewConsumer(pusher *Pusher) (*Consumer, error) {
|
|||||||
|
|
||||||
func (c *Consumer) Start() {
|
func (c *Consumer) Start() {
|
||||||
go c.pushCh.pushConsumerGroup.RegisterHandleAndConsumer(context.Background(), &c.pushCh)
|
go c.pushCh.pushConsumerGroup.RegisterHandleAndConsumer(context.Background(), &c.pushCh)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,14 @@ import (
|
|||||||
|
|
||||||
firebase "firebase.google.com/go"
|
firebase "firebase.google.com/go"
|
||||||
"firebase.google.com/go/messaging"
|
"firebase.google.com/go/messaging"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
"google.golang.org/api/option"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/redis/go-redis/v9"
|
|
||||||
"google.golang.org/api/option"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const SinglePushCountLimit = 400
|
const SinglePushCountLimit = 400
|
||||||
@ -39,9 +41,9 @@ type Fcm struct {
|
|||||||
|
|
||||||
// NewClient initializes a new FCM client using the Firebase Admin SDK.
|
// NewClient initializes a new FCM client using the Firebase Admin SDK.
|
||||||
// It requires the FCM service account credentials file located within the project's configuration directory.
|
// It requires the FCM service account credentials file located within the project's configuration directory.
|
||||||
func NewClient(cache cache.MsgModel) *Fcm {
|
func NewClient(globalConfig *config.GlobalConfig, cache cache.MsgModel) *Fcm {
|
||||||
projectRoot, _ := config.GetProjectRoot()
|
projectRoot := config.GetProjectRoot()
|
||||||
credentialsFilePath := filepath.Join(projectRoot, "config", config.Config.Push.Fcm.ServiceAccount)
|
credentialsFilePath := filepath.Join(projectRoot, "config", globalConfig.Push.Fcm.ServiceAccount)
|
||||||
opt := option.WithCredentialsFile(credentialsFilePath)
|
opt := option.WithCredentialsFile(credentialsFilePath)
|
||||||
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -133,13 +133,13 @@ type Payload struct {
|
|||||||
IsSignal bool `json:"isSignal"`
|
IsSignal bool `json:"isSignal"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPushReq(title, content string) PushReq {
|
func newPushReq(config *config.GlobalConfig, title, content string) PushReq {
|
||||||
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
||||||
Title: title,
|
Title: title,
|
||||||
Body: content,
|
Body: content,
|
||||||
ClickType: "startapp",
|
ClickType: "startapp",
|
||||||
ChannelID: config.Config.Push.GeTui.ChannelID,
|
ChannelID: config.Push.GeTui.ChannelID,
|
||||||
ChannelName: config.Config.Push.GeTui.ChannelName,
|
ChannelName: config.Push.GeTui.ChannelName,
|
||||||
}}}
|
}}}
|
||||||
return pushReq
|
return pushReq
|
||||||
}
|
}
|
||||||
|
@ -55,10 +55,15 @@ type Client struct {
|
|||||||
cache cache.MsgModel
|
cache cache.MsgModel
|
||||||
tokenExpireTime int64
|
tokenExpireTime int64
|
||||||
taskIDTTL int64
|
taskIDTTL int64
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(cache cache.MsgModel) *Client {
|
func NewClient(config *config.GlobalConfig, cache cache.MsgModel) *Client {
|
||||||
return &Client{cache: cache, tokenExpireTime: tokenExpireTime, taskIDTTL: taskIDTTL}
|
return &Client{cache: cache,
|
||||||
|
tokenExpireTime: tokenExpireTime,
|
||||||
|
taskIDTTL: taskIDTTL,
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error {
|
func (g *Client) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error {
|
||||||
@ -74,7 +79,7 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pushReq := newPushReq(title, content)
|
pushReq := newPushReq(g.config, title, content)
|
||||||
pushReq.setPushChannel(title, content)
|
pushReq.setPushChannel(title, content)
|
||||||
if len(userIDs) > 1 {
|
if len(userIDs) > 1 {
|
||||||
maxNum := 999
|
maxNum := 999
|
||||||
@ -85,9 +90,9 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
for i, v := range s.GetSplitResult() {
|
for i, v := range s.GetSplitResult() {
|
||||||
go func(index int, userIDs []string) {
|
go func(index int, userIDs []string) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
if err2 := g.batchPush(ctx, token, userIDs, pushReq); err2 != nil {
|
if err := g.batchPush(ctx, token, userIDs, pushReq); err != nil {
|
||||||
log.ZError(ctx, "batchPush failed", err2, "index", index, "token", token, "req", pushReq)
|
log.ZError(ctx, "batchPush failed", err, "index", index, "token", token, "req", pushReq)
|
||||||
err = err2
|
err = err
|
||||||
}
|
}
|
||||||
}(i, v.Item)
|
}(i, v.Item)
|
||||||
}
|
}
|
||||||
@ -110,13 +115,13 @@ func (g *Client) Push(ctx context.Context, userIDs []string, title, content stri
|
|||||||
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
h.Write(
|
h.Write(
|
||||||
[]byte(config.Config.Push.GeTui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.GeTui.MasterSecret),
|
[]byte(g.config.Push.GeTui.AppKey + strconv.Itoa(int(timeStamp)) + g.config.Push.GeTui.MasterSecret),
|
||||||
)
|
)
|
||||||
sign := hex.EncodeToString(h.Sum(nil))
|
sign := hex.EncodeToString(h.Sum(nil))
|
||||||
reqAuth := AuthReq{
|
reqAuth := AuthReq{
|
||||||
Sign: sign,
|
Sign: sign,
|
||||||
Timestamp: strconv.Itoa(int(timeStamp)),
|
Timestamp: strconv.Itoa(int(timeStamp)),
|
||||||
AppKey: config.Config.Push.GeTui.AppKey,
|
AppKey: g.config.Push.GeTui.AppKey,
|
||||||
}
|
}
|
||||||
respAuth := AuthResp{}
|
respAuth := AuthResp{}
|
||||||
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
||||||
@ -159,7 +164,7 @@ func (g *Client) request(ctx context.Context, url string, input any, token strin
|
|||||||
header := map[string]string{"token": token}
|
header := map[string]string{"token": token}
|
||||||
resp := &Resp{}
|
resp := &Resp{}
|
||||||
resp.Data = output
|
resp.Data = output
|
||||||
return g.postReturn(ctx, config.Config.Push.GeTui.PushUrl+url, header, input, resp, 3)
|
return g.postReturn(ctx, g.config.Push.GeTui.PushUrl+url, header, input, resp, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) postReturn(
|
func (g *Client) postReturn(
|
||||||
|
@ -46,7 +46,6 @@ type Extras struct {
|
|||||||
func (n *Notification) SetAlert(alert string) {
|
func (n *Notification) SetAlert(alert string) {
|
||||||
n.Alert = alert
|
n.Alert = alert
|
||||||
n.Android.Alert = alert
|
n.Android.Alert = alert
|
||||||
n.SetAndroidIntent()
|
|
||||||
n.IOS.Alert = alert
|
n.IOS.Alert = alert
|
||||||
n.IOS.Sound = "default"
|
n.IOS.Sound = "default"
|
||||||
n.IOS.Badge = "+1"
|
n.IOS.Badge = "+1"
|
||||||
@ -57,8 +56,8 @@ func (n *Notification) SetExtras(extras Extras) {
|
|||||||
n.Android.Extras = extras
|
n.Android.Extras = extras
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) SetAndroidIntent() {
|
func (n *Notification) SetAndroidIntent(config *config.GlobalConfig) {
|
||||||
n.Android.Intent.URL = config.Config.Push.Jpns.PushIntent
|
n.Android.Intent.URL = config.Push.Jpns.PushIntent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Notification) IOSEnableMutableContent() {
|
func (n *Notification) IOSEnableMutableContent() {
|
||||||
|
@ -25,10 +25,12 @@ import (
|
|||||||
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
http2 "github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type JPush struct{}
|
type JPush struct {
|
||||||
|
config *config.GlobalConfig
|
||||||
|
}
|
||||||
|
|
||||||
func NewClient() *JPush {
|
func NewClient(config *config.GlobalConfig) *JPush {
|
||||||
return &JPush{}
|
return &JPush{config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *JPush) Auth(apiKey, secretKey string, timeStamp int64) (token string, err error) {
|
func (j *JPush) Auth(apiKey, secretKey string, timeStamp int64) (token string, err error) {
|
||||||
@ -59,10 +61,12 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
|||||||
no.IOSEnableMutableContent()
|
no.IOSEnableMutableContent()
|
||||||
no.SetExtras(extras)
|
no.SetExtras(extras)
|
||||||
no.SetAlert(title)
|
no.SetAlert(title)
|
||||||
|
no.SetAndroidIntent(j.config)
|
||||||
|
|
||||||
var msg body.Message
|
var msg body.Message
|
||||||
msg.SetMsgContent(content)
|
msg.SetMsgContent(content)
|
||||||
var opt body.Options
|
var opt body.Options
|
||||||
opt.SetApnsProduction(config.Config.IOSPush.Production)
|
opt.SetApnsProduction(j.config.IOSPush.Production)
|
||||||
var pushObj body.PushObj
|
var pushObj body.PushObj
|
||||||
pushObj.SetPlatform(&pf)
|
pushObj.SetPlatform(&pf)
|
||||||
pushObj.SetAudience(&au)
|
pushObj.SetAudience(&au)
|
||||||
@ -76,9 +80,9 @@ func (j *JPush) Push(ctx context.Context, userIDs []string, title, content strin
|
|||||||
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
func (j *JPush) request(ctx context.Context, po body.PushObj, resp any, timeout int) error {
|
||||||
return http2.PostReturn(
|
return http2.PostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Push.Jpns.PushUrl,
|
j.config.Push.Jpns.PushUrl,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"Authorization": j.getAuthorization(config.Config.Push.Jpns.AppKey, config.Config.Push.Jpns.MasterSecret),
|
"Authorization": j.getAuthorization(j.config.Push.Jpns.AppKey, j.config.Push.Jpns.MasterSecret),
|
||||||
},
|
},
|
||||||
po,
|
po,
|
||||||
resp,
|
resp,
|
||||||
|
@ -33,15 +33,29 @@ type ConsumerHandler struct {
|
|||||||
pusher *Pusher
|
pusher *Pusher
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsumerHandler(pusher *Pusher) (*ConsumerHandler, error) {
|
func NewConsumerHandler(config *config.GlobalConfig, pusher *Pusher) (*ConsumerHandler, error) {
|
||||||
var consumerHandler ConsumerHandler
|
var consumerHandler ConsumerHandler
|
||||||
consumerHandler.pusher = pusher
|
consumerHandler.pusher = pusher
|
||||||
var err error
|
var err error
|
||||||
|
var tlsConfig *kfk.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kfk.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
consumerHandler.pushConsumerGroup, err = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
consumerHandler.pushConsumerGroup, err = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
|
||||||
KafkaVersion: sarama.V2_0_0_0,
|
KafkaVersion: sarama.V2_0_0_0,
|
||||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
|
OffsetsInitial: sarama.OffsetNewest,
|
||||||
}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
|
IsReturnErr: false,
|
||||||
config.Config.Kafka.ConsumerGroupID.MsgToPush)
|
UserName: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}, []string{config.Kafka.MsgToPush.Topic}, config.Kafka.Addr,
|
||||||
|
config.Kafka.ConsumerGroupID.MsgToPush,
|
||||||
|
tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package push
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbpush "github.com/OpenIMSDK/protocol/push"
|
pbpush "github.com/OpenIMSDK/protocol/push"
|
||||||
@ -31,20 +32,22 @@ import (
|
|||||||
|
|
||||||
type pushServer struct {
|
type pushServer struct {
|
||||||
pusher *Pusher
|
pusher *Pusher
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
cacheModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
offlinePusher := NewOfflinePusher(cacheModel)
|
offlinePusher := NewOfflinePusher(config, cacheModel)
|
||||||
database := controller.NewPushDatabase(cacheModel)
|
database := controller.NewPushDatabase(cacheModel)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
pusher := NewPusher(
|
pusher := NewPusher(
|
||||||
|
config,
|
||||||
client,
|
client,
|
||||||
offlinePusher,
|
offlinePusher,
|
||||||
database,
|
database,
|
||||||
@ -57,9 +60,10 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
|
|
||||||
pbpush.RegisterPushMsgServiceServer(server, &pushServer{
|
pbpush.RegisterPushMsgServiceServer(server, &pushServer{
|
||||||
pusher: pusher,
|
pusher: pusher,
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
|
|
||||||
consumer, err := NewConsumer(pusher)
|
consumer, err := NewConsumer(config, pusher)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Pusher struct {
|
type Pusher struct {
|
||||||
|
config *config.GlobalConfig
|
||||||
database controller.PushDatabase
|
database controller.PushDatabase
|
||||||
discov discoveryregistry.SvcDiscoveryRegistry
|
discov discoveryregistry.SvcDiscoveryRegistry
|
||||||
offlinePusher offlinepush.OfflinePusher
|
offlinePusher offlinepush.OfflinePusher
|
||||||
@ -57,11 +58,12 @@ type Pusher struct {
|
|||||||
|
|
||||||
var errNoOfflinePusher = errors.New("no offlinePusher is configured")
|
var errNoOfflinePusher = errors.New("no offlinePusher is configured")
|
||||||
|
|
||||||
func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
|
func NewPusher(config *config.GlobalConfig, discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
|
||||||
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache,
|
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache,
|
||||||
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
|
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
|
||||||
) *Pusher {
|
) *Pusher {
|
||||||
return &Pusher{
|
return &Pusher{
|
||||||
|
config: config,
|
||||||
discov: discov,
|
discov: discov,
|
||||||
database: database,
|
database: database,
|
||||||
offlinePusher: offlinePusher,
|
offlinePusher: offlinePusher,
|
||||||
@ -73,15 +75,15 @@ func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOfflinePusher(cache cache.MsgModel) offlinepush.OfflinePusher {
|
func NewOfflinePusher(config *config.GlobalConfig, cache cache.MsgModel) offlinepush.OfflinePusher {
|
||||||
var offlinePusher offlinepush.OfflinePusher
|
var offlinePusher offlinepush.OfflinePusher
|
||||||
switch config.Config.Push.Enable {
|
switch config.Push.Enable {
|
||||||
case "getui":
|
case "getui":
|
||||||
offlinePusher = getui.NewClient(cache)
|
offlinePusher = getui.NewClient(config, cache)
|
||||||
case "fcm":
|
case "fcm":
|
||||||
offlinePusher = fcm.NewClient(cache)
|
offlinePusher = fcm.NewClient(config, cache)
|
||||||
case "jpush":
|
case "jpush":
|
||||||
offlinePusher = jpush.NewClient()
|
offlinePusher = jpush.NewClient(config)
|
||||||
default:
|
default:
|
||||||
offlinePusher = dummy.NewClient()
|
offlinePusher = dummy.NewClient()
|
||||||
}
|
}
|
||||||
@ -99,7 +101,7 @@ func (p *Pusher) DeleteMemberAndSetConversationSeq(ctx context.Context, groupID
|
|||||||
|
|
||||||
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.MsgData) error {
|
||||||
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
log.ZDebug(ctx, "Get msg from msg_transfer And push msg", "userIDs", userIDs, "msg", msg.String())
|
||||||
if err := callbackOnlinePush(ctx, userIDs, msg); err != nil {
|
if err := callbackOnlinePush(ctx, p.config, userIDs, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// push
|
// push
|
||||||
@ -127,7 +129,7 @@ func (p *Pusher) Push2User(ctx context.Context, userIDs []string, msg *sdkws.Msg
|
|||||||
})
|
})
|
||||||
|
|
||||||
if len(offlinePushUserIDList) > 0 {
|
if len(offlinePushUserIDList) > 0 {
|
||||||
if err = callbackOfflinePush(ctx, offlinePushUserIDList, msg, &[]string{}); err != nil {
|
if err = callbackOfflinePush(ctx, p.config, offlinePushUserIDList, msg, &[]string{}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = p.offlinePushMsg(ctx, msg.SendID, msg, offlinePushUserIDList)
|
err = p.offlinePushMsg(ctx, msg.SendID, msg, offlinePushUserIDList)
|
||||||
@ -160,7 +162,7 @@ func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string,
|
|||||||
}
|
}
|
||||||
if len(needOfflinePushUserIDs) > 0 {
|
if len(needOfflinePushUserIDs) > 0 {
|
||||||
var offlinePushUserIDs []string
|
var offlinePushUserIDs []string
|
||||||
err := callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
err := callbackOfflinePush(ctx, p.config, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -191,7 +193,7 @@ func (p *Pusher) k8sOfflinePush2SuperGroup(ctx context.Context, groupID string,
|
|||||||
func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
|
func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws.MsgData) (err error) {
|
||||||
log.ZDebug(ctx, "Get super group msg from msg_transfer and push msg", "msg", msg.String(), "groupID", groupID)
|
log.ZDebug(ctx, "Get super group msg from msg_transfer and push msg", "msg", msg.String(), "groupID", groupID)
|
||||||
var pushToUserIDs []string
|
var pushToUserIDs []string
|
||||||
if err = callbackBeforeSuperGroupOnlinePush(ctx, groupID, msg, &pushToUserIDs); err != nil {
|
if err = callbackBeforeSuperGroupOnlinePush(ctx, p.config, groupID, msg, &pushToUserIDs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,11 +235,11 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "GroupDismissedNotificationInfo****", "groupID", groupID, "num", len(pushToUserIDs), "list", pushToUserIDs)
|
log.ZInfo(ctx, "GroupDismissedNotificationInfo****", "groupID", groupID, "num", len(pushToUserIDs), "list", pushToUserIDs)
|
||||||
if len(config.Config.Manager.UserID) > 0 {
|
if len(p.config.Manager.UserID) > 0 {
|
||||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.Manager.UserID[0])
|
ctx = mcontext.WithOpUserIDContext(ctx, p.config.Manager.UserID[0])
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) == 0 && len(config.Config.IMAdmin.UserID) > 0 {
|
if len(p.config.Manager.UserID) == 0 && len(p.config.IMAdmin.UserID) > 0 {
|
||||||
ctx = mcontext.WithOpUserIDContext(ctx, config.Config.IMAdmin.UserID[0])
|
ctx = mcontext.WithOpUserIDContext(ctx, p.config.IMAdmin.UserID[0])
|
||||||
}
|
}
|
||||||
defer func(groupID string) {
|
defer func(groupID string) {
|
||||||
if err = p.groupRpcClient.DismissGroup(ctx, groupID); err != nil {
|
if err = p.groupRpcClient.DismissGroup(ctx, groupID); err != nil {
|
||||||
@ -255,10 +257,10 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
|
|
||||||
log.ZDebug(ctx, "get conn and online push success", "result", wsResults, "msg", msg)
|
log.ZDebug(ctx, "get conn and online push success", "result", wsResults, "msg", msg)
|
||||||
isOfflinePush := utils.GetSwitchFromOptions(msg.Options, constant.IsOfflinePush)
|
isOfflinePush := utils.GetSwitchFromOptions(msg.Options, constant.IsOfflinePush)
|
||||||
if isOfflinePush && config.Config.Envs.Discovery == "k8s" {
|
if isOfflinePush && p.config.Envs.Discovery == "k8s" {
|
||||||
return p.k8sOfflinePush2SuperGroup(ctx, groupID, msg, wsResults)
|
return p.k8sOfflinePush2SuperGroup(ctx, groupID, msg, wsResults)
|
||||||
}
|
}
|
||||||
if isOfflinePush && config.Config.Envs.Discovery == "zookeeper" {
|
if isOfflinePush && p.config.Envs.Discovery == "zookeeper" {
|
||||||
var (
|
var (
|
||||||
onlineSuccessUserIDs = []string{msg.SendID}
|
onlineSuccessUserIDs = []string{msg.SendID}
|
||||||
webAndPcBackgroundUserIDs []string
|
webAndPcBackgroundUserIDs []string
|
||||||
@ -296,7 +298,7 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
|
|||||||
// Use offline push messaging
|
// Use offline push messaging
|
||||||
if len(needOfflinePushUserIDs) > 0 {
|
if len(needOfflinePushUserIDs) > 0 {
|
||||||
var offlinePushUserIDs []string
|
var offlinePushUserIDs []string
|
||||||
err = callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
err = callbackOfflinePush(ctx, p.config, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -355,7 +357,7 @@ func (p *Pusher) k8sOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUs
|
|||||||
var (
|
var (
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
wg = errgroup.Group{}
|
wg = errgroup.Group{}
|
||||||
maxWorkers = config.Config.Push.MaxConcurrentWorkers
|
maxWorkers = p.config.Push.MaxConcurrentWorkers
|
||||||
)
|
)
|
||||||
if maxWorkers < 3 {
|
if maxWorkers < 3 {
|
||||||
maxWorkers = 3
|
maxWorkers = 3
|
||||||
@ -384,10 +386,10 @@ func (p *Pusher) k8sOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUs
|
|||||||
return wsResults, nil
|
return wsResults, nil
|
||||||
}
|
}
|
||||||
func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) (wsResults []*msggateway.SingleMsgToUserResults, err error) {
|
func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData, pushToUserIDs []string) (wsResults []*msggateway.SingleMsgToUserResults, err error) {
|
||||||
if config.Config.Envs.Discovery == "k8s" {
|
if p.config.Envs.Discovery == "k8s" {
|
||||||
return p.k8sOnlinePush(ctx, msg, pushToUserIDs)
|
return p.k8sOnlinePush(ctx, msg, pushToUserIDs)
|
||||||
}
|
}
|
||||||
conns, err := p.discov.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := p.discov.GetConns(ctx, p.config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
log.ZDebug(ctx, "get gateway conn", "conn length", len(conns))
|
log.ZDebug(ctx, "get gateway conn", "conn length", len(conns))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -397,7 +399,7 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
|
|||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
wg = errgroup.Group{}
|
wg = errgroup.Group{}
|
||||||
input = &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs}
|
input = &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs}
|
||||||
maxWorkers = config.Config.Push.MaxConcurrentWorkers
|
maxWorkers = p.config.Push.MaxConcurrentWorkers
|
||||||
)
|
)
|
||||||
|
|
||||||
if maxWorkers < 3 {
|
if maxWorkers < 3 {
|
||||||
|
@ -38,29 +38,32 @@ type authServer struct {
|
|||||||
authDatabase controller.AuthDatabase
|
authDatabase controller.AuthDatabase
|
||||||
userRpcClient *rpcclient.UserRpcClient
|
userRpcClient *rpcclient.UserRpcClient
|
||||||
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
|
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
pbauth.RegisterAuthServer(server, &authServer{
|
pbauth.RegisterAuthServer(server, &authServer{
|
||||||
userRpcClient: &userRpcClient,
|
userRpcClient: &userRpcClient,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
authDatabase: controller.NewAuthDatabase(
|
authDatabase: controller.NewAuthDatabase(
|
||||||
cache.NewMsgCacheModel(rdb),
|
cache.NewMsgCacheModel(rdb, config),
|
||||||
config.Config.Secret,
|
config.Secret,
|
||||||
config.Config.TokenPolicy.Expire,
|
config.TokenPolicy.Expire,
|
||||||
|
config,
|
||||||
),
|
),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*pbauth.UserTokenResp, error) {
|
func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*pbauth.UserTokenResp, error) {
|
||||||
resp := pbauth.UserTokenResp{}
|
resp := pbauth.UserTokenResp{}
|
||||||
if req.Secret != config.Config.Secret {
|
if req.Secret != s.config.Secret {
|
||||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
if _, err := s.userRpcClient.GetUserInfo(ctx, req.UserID); err != nil {
|
||||||
@ -72,17 +75,17 @@ func (s *authServer) UserToken(ctx context.Context, req *pbauth.UserTokenReq) (*
|
|||||||
}
|
}
|
||||||
prommetrics.UserLoginCounter.Inc()
|
prommetrics.UserLoginCounter.Inc()
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenReq) (*pbauth.GetUserTokenResp, error) {
|
func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenReq) (*pbauth.GetUserTokenResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp := pbauth.GetUserTokenResp{}
|
resp := pbauth.GetUserTokenResp{}
|
||||||
|
|
||||||
if authverify.IsManagerUserID(req.UserID) {
|
if authverify.IsManagerUserID(req.UserID, s.config) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("don't get Admin token")
|
return nil, errs.ErrNoPermission.Wrap("don't get Admin token")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,12 +97,12 @@ func (s *authServer) GetUserToken(ctx context.Context, req *pbauth.GetUserTokenR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp.Token = token
|
resp.Token = token
|
||||||
resp.ExpireTimeSeconds = config.Config.TokenPolicy.Expire * 24 * 60 * 60
|
resp.ExpireTimeSeconds = s.config.TokenPolicy.Expire * 24 * 60 * 60
|
||||||
return &resp, nil
|
return &resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) {
|
func (s *authServer) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) {
|
||||||
claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret())
|
claims, err = tokenverify.GetClaimFromToken(tokensString, authverify.Secret(s.config.Secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err)
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
@ -139,7 +142,7 @@ func (s *authServer) ParseToken(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq) (*pbauth.ForceLogoutResp, error) {
|
func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq) (*pbauth.ForceLogoutResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
|
if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
|
||||||
@ -149,7 +152,7 @@ func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
|
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
|
||||||
conns, err := s.RegisterCenter.GetConns(ctx, config.Config.RpcRegisterName.OpenImMessageGatewayName)
|
conns, err := s.RegisterCenter.GetConns(ctx, s.config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package conversation
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
@ -44,6 +45,7 @@ type conversationServer struct {
|
|||||||
groupRpcClient *rpcclient.GroupRpcClient
|
groupRpcClient *rpcclient.GroupRpcClient
|
||||||
conversationDatabase controller.ConversationDatabase
|
conversationDatabase controller.ConversationDatabase
|
||||||
conversationNotificationSender *notification.ConversationNotificationSender
|
conversationNotificationSender *notification.ConversationNotificationSender
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
||||||
@ -54,28 +56,29 @@ func (c *conversationServer) GetConversationNotReceiveMessageUserIDs(
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
pbconversation.RegisterConversationServer(server, &conversationServer{
|
pbconversation.RegisterConversationServer(server, &conversationServer{
|
||||||
msgRpcClient: &msgRpcClient,
|
msgRpcClient: &msgRpcClient,
|
||||||
user: &userRpcClient,
|
user: &userRpcClient,
|
||||||
conversationNotificationSender: notification.NewConversationNotificationSender(&msgRpcClient),
|
conversationNotificationSender: notification.NewConversationNotificationSender(config, &msgRpcClient),
|
||||||
groupRpcClient: &groupRpcClient,
|
groupRpcClient: &groupRpcClient,
|
||||||
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB), tx.NewMongo(mongo.GetClient())),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlac
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) (*pbfriend.AddBlackResp, error) {
|
func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) (*pbfriend.AddBlackResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
_, err := s.userRpcClient.GetUsersInfo(ctx, []string{req.OwnerUserID, req.BlackUserID})
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) error {
|
func CallbackBeforeAddFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ApplyToAddFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddFriend.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddFriendReq{
|
cbReq := &cbapi.CallbackBeforeAddFriendReq{
|
||||||
@ -36,14 +36,14 @@ func CallbackBeforeAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriend
|
|||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddFriendResp{}
|
resp := &cbapi.CallbackBeforeAddFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
func CallbackBeforeSetFriendRemark(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.SetFriendRemarkReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSetFriendRemark.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetFriendRemark.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeSetFriendRemarkReq{
|
cbReq := &cbapi.CallbackBeforeSetFriendRemarkReq{
|
||||||
@ -53,15 +53,15 @@ func CallbackBeforeSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendR
|
|||||||
Remark: req.Remark,
|
Remark: req.Remark,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSetFriendRemarkResp{}
|
resp := &cbapi.CallbackBeforeSetFriendRemarkResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.Remark, &resp.Remark)
|
utils.NotNilReplace(&req.Remark, &resp.Remark)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) error {
|
func CallbackAfterSetFriendRemark(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.SetFriendRemarkReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSetFriendRemark.Enable {
|
if !globalConfig.Callback.CallbackAfterSetFriendRemark.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterSetFriendRemarkReq{
|
cbReq := &cbapi.CallbackAfterSetFriendRemarkReq{
|
||||||
@ -71,13 +71,13 @@ func CallbackAfterSetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRe
|
|||||||
Remark: req.Remark,
|
Remark: req.Remark,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSetFriendRemarkResp{}
|
resp := &cbapi.CallbackAfterSetFriendRemarkResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeAddBlack(ctx context.Context, req *pbfriend.AddBlackReq) error {
|
func CallbackBeforeAddBlack(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.AddBlackReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddBlack.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddBlack.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddBlackReq{
|
cbReq := &cbapi.CallbackBeforeAddBlackReq{
|
||||||
@ -86,13 +86,13 @@ func CallbackBeforeAddBlack(ctx context.Context, req *pbfriend.AddBlackReq) erro
|
|||||||
BlackUserID: req.BlackUserID,
|
BlackUserID: req.BlackUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddBlackResp{}
|
resp := &cbapi.CallbackBeforeAddBlackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddBlack); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddBlack); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) error {
|
func CallbackAfterAddFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ApplyToAddFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterAddFriend.Enable {
|
if !globalConfig.Callback.CallbackAfterAddFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterAddFriendReq{
|
cbReq := &cbapi.CallbackAfterAddFriendReq{
|
||||||
@ -102,14 +102,14 @@ func CallbackAfterAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendR
|
|||||||
ReqMsg: req.ReqMsg,
|
ReqMsg: req.ReqMsg,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterAddFriendResp{}
|
resp := &cbapi.CallbackAfterAddFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterAddFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterAddFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeAddFriendAgree(ctx context.Context, req *pbfriend.RespondFriendApplyReq) error {
|
func CallbackBeforeAddFriendAgree(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.RespondFriendApplyReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeAddFriendAgree.Enable {
|
if !globalConfig.Callback.CallbackBeforeAddFriendAgree.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeAddFriendAgreeReq{
|
cbReq := &cbapi.CallbackBeforeAddFriendAgreeReq{
|
||||||
@ -120,13 +120,13 @@ func CallbackBeforeAddFriendAgree(ctx context.Context, req *pbfriend.RespondFrie
|
|||||||
HandleResult: req.HandleResult,
|
HandleResult: req.HandleResult,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeAddFriendAgreeResp{}
|
resp := &cbapi.CallbackBeforeAddFriendAgreeResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeAddFriendAgree); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeAddFriendAgree); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterDeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendReq) error {
|
func CallbackAfterDeleteFriend(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.DeleteFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterDeleteFriend.Enable {
|
if !globalConfig.Callback.CallbackAfterDeleteFriend.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterDeleteFriendReq{
|
cbReq := &cbapi.CallbackAfterDeleteFriendReq{
|
||||||
@ -135,13 +135,13 @@ func CallbackAfterDeleteFriend(ctx context.Context, req *pbfriend.DeleteFriendRe
|
|||||||
FriendUserID: req.FriendUserID,
|
FriendUserID: req.FriendUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterDeleteFriendResp{}
|
resp := &cbapi.CallbackAfterDeleteFriendResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterDeleteFriend); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterDeleteFriend); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
func CallbackBeforeImportFriends(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ImportFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeImportFriends.Enable {
|
if !globalConfig.Callback.CallbackBeforeImportFriends.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
cbReq := &cbapi.CallbackBeforeImportFriendsReq{
|
||||||
@ -150,7 +150,7 @@ func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriend
|
|||||||
FriendUserIDs: req.FriendUserIDs,
|
FriendUserIDs: req.FriendUserIDs,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeImportFriendsResp{}
|
resp := &cbapi.CallbackBeforeImportFriendsResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeImportFriends); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeImportFriends); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(resp.FriendUserIDs) != 0 {
|
if len(resp.FriendUserIDs) != 0 {
|
||||||
@ -158,8 +158,8 @@ func CallbackBeforeImportFriends(ctx context.Context, req *pbfriend.ImportFriend
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) error {
|
func CallbackAfterImportFriends(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.ImportFriendReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterImportFriends.Enable {
|
if !globalConfig.Callback.CallbackAfterImportFriends.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterImportFriendsReq{
|
cbReq := &cbapi.CallbackAfterImportFriendsReq{
|
||||||
@ -168,14 +168,14 @@ func CallbackAfterImportFriends(ctx context.Context, req *pbfriend.ImportFriendR
|
|||||||
FriendUserIDs: req.FriendUserIDs,
|
FriendUserIDs: req.FriendUserIDs,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterImportFriendsResp{}
|
resp := &cbapi.CallbackAfterImportFriendsResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterImportFriends); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterImportFriends); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterRemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq) error {
|
func CallbackAfterRemoveBlack(ctx context.Context, globalConfig *config.GlobalConfig, req *pbfriend.RemoveBlackReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterRemoveBlack.Enable {
|
if !globalConfig.Callback.CallbackAfterRemoveBlack.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterRemoveBlackReq{
|
cbReq := &cbapi.CallbackAfterRemoveBlackReq{
|
||||||
@ -184,7 +184,7 @@ func CallbackAfterRemoveBlack(ctx context.Context, req *pbfriend.RemoveBlackReq)
|
|||||||
BlackUserID: req.BlackUserID,
|
BlackUserID: req.BlackUserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterRemoveBlackResp{}
|
resp := &cbapi.CallbackAfterRemoveBlackResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterRemoveBlack); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterRemoveBlack); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -16,25 +16,33 @@ package friend
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
pbfriend "github.com/OpenIMSDK/protocol/friend"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type friendServer struct {
|
type friendServer struct {
|
||||||
@ -44,42 +52,44 @@ type friendServer struct {
|
|||||||
notificationSender *notification.FriendNotificationSender
|
notificationSender *notification.FriendNotificationSender
|
||||||
conversationRpcClient rpcclient.ConversationRpcClient
|
conversationRpcClient rpcclient.ConversationRpcClient
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
// Initialize MongoDB
|
// Initialize MongoDB
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Redis
|
// Initialize Redis
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase())
|
friendMongoDB, err := mgo.NewFriendMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase())
|
friendRequestMongoDB, err := mgo.NewFriendRequestMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase())
|
blackMongoDB, err := mgo.NewBlackMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize RPC clients
|
// Initialize RPC clients
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
|
|
||||||
// Initialize notification sender
|
// Initialize notification sender
|
||||||
notificationSender := notification.NewFriendNotificationSender(
|
notificationSender := notification.NewFriendNotificationSender(
|
||||||
|
config,
|
||||||
&msgRpcClient,
|
&msgRpcClient,
|
||||||
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
notification.WithRpcFunc(userRpcClient.GetUsersInfo),
|
||||||
)
|
)
|
||||||
@ -98,7 +108,8 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
userRpcClient: &userRpcClient,
|
userRpcClient: &userRpcClient,
|
||||||
notificationSender: notificationSender,
|
notificationSender: notificationSender,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
conversationRpcClient: rpcclient.NewConversationRpcClient(client),
|
conversationRpcClient: rpcclient.NewConversationRpcClient(client, config),
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -106,15 +117,14 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
|||||||
|
|
||||||
// ok.
|
// ok.
|
||||||
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.ApplyToAddFriendReq) (resp *pbfriend.ApplyToAddFriendResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
|
||||||
resp = &pbfriend.ApplyToAddFriendResp{}
|
resp = &pbfriend.ApplyToAddFriendResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.FromUserID,s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.ToUserID == req.FromUserID {
|
if req.ToUserID == req.FromUserID {
|
||||||
return nil, errs.ErrCanNotAddYourself.Wrap()
|
return nil, errs.ErrCanNotAddYourself.Wrap("req.ToUserID", req.ToUserID)
|
||||||
}
|
}
|
||||||
if err = CallbackBeforeAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackBeforeAddFriend(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
|
if _, err := s.userRpcClient.GetUsersInfoMap(ctx, []string{req.ToUserID, req.FromUserID}); err != nil {
|
||||||
@ -131,7 +141,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendApplicationAddNotification(ctx, req)
|
s.notificationSender.FriendApplicationAddNotification(ctx, req)
|
||||||
if err = CallbackAfterAddFriend(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackAfterAddFriend(ctx,s.config ,req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -140,7 +150,7 @@ func (s *friendServer) ApplyToAddFriend(ctx context.Context, req *pbfriend.Apply
|
|||||||
// ok.
|
// ok.
|
||||||
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFriendReq) (resp *pbfriend.ImportFriendResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, err := s.userRpcClient.GetUsersInfo(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil {
|
if _, err := s.userRpcClient.GetUsersInfo(ctx, append([]string{req.OwnerUserID}, req.FriendUserIDs...)); err != nil {
|
||||||
@ -152,7 +162,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
if utils.Duplicate(req.FriendUserIDs) {
|
if utils.Duplicate(req.FriendUserIDs) {
|
||||||
return nil, errs.ErrArgs.Wrap("friend userID repeated")
|
return nil, errs.ErrArgs.Wrap("friend userID repeated")
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeImportFriends(ctx, req); err != nil {
|
if err := CallbackBeforeImportFriends(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +176,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
HandleResult: constant.FriendResponseAgree,
|
HandleResult: constant.FriendResponseAgree,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := CallbackAfterImportFriends(ctx, req); err != nil {
|
if err := CallbackAfterImportFriends(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &pbfriend.ImportFriendResp{}, nil
|
return &pbfriend.ImportFriendResp{}, nil
|
||||||
@ -176,7 +186,7 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbfriend.ImportFr
|
|||||||
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.RespondFriendApplyReq) (resp *pbfriend.RespondFriendApplyResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
resp = &pbfriend.RespondFriendApplyResp{}
|
resp = &pbfriend.RespondFriendApplyResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.ToUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.ToUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +197,7 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res
|
|||||||
HandleResult: req.HandleResult,
|
HandleResult: req.HandleResult,
|
||||||
}
|
}
|
||||||
if req.HandleResult == constant.FriendResponseAgree {
|
if req.HandleResult == constant.FriendResponseAgree {
|
||||||
if err := CallbackBeforeAddFriendAgree(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err := CallbackBeforeAddFriendAgree(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err := s.friendDatabase.AgreeFriendRequest(ctx, &friendRequest)
|
err := s.friendDatabase.AgreeFriendRequest(ctx, &friendRequest)
|
||||||
@ -223,7 +233,7 @@ func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFri
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendDeletedNotification(ctx, req)
|
s.notificationSender.FriendDeletedNotification(ctx, req)
|
||||||
if err := CallbackAfterDeleteFriend(ctx, req); err != nil {
|
if err := CallbackAfterDeleteFriend(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -233,7 +243,7 @@ func (s *friendServer) DeleteFriend(ctx context.Context, req *pbfriend.DeleteFri
|
|||||||
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFriendRemarkReq) (resp *pbfriend.SetFriendRemarkResp, err error) {
|
||||||
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
defer log.ZInfo(ctx, utils.GetFuncName()+" Return")
|
||||||
|
|
||||||
if err = CallbackBeforeSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err = CallbackBeforeSetFriendRemark(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp = &pbfriend.SetFriendRemarkResp{}
|
resp = &pbfriend.SetFriendRemarkResp{}
|
||||||
@ -247,7 +257,7 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *pbfriend.SetFri
|
|||||||
if err := s.friendDatabase.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
if err := s.friendDatabase.UpdateRemark(ctx, req.OwnerUserID, req.FriendUserID, req.Remark); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := CallbackAfterSetFriendRemark(ctx, req); err != nil && err != errs.ErrCallbackContinue {
|
if err := CallbackAfterSetFriendRemark(ctx, s.config, req); err != nil && err != errs.ErrCallbackContinue {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
s.notificationSender.FriendRemarkSetNotification(ctx, req.OwnerUserID, req.FriendUserID)
|
||||||
|
@ -32,8 +32,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) {
|
func CallbackBeforeCreateGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.CreateGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeCreateGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeCreateGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackBeforeCreateGroupReq{
|
cbReq := &callbackstruct.CallbackBeforeCreateGroupReq{
|
||||||
@ -58,7 +58,7 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeCreateGroupResp{}
|
resp := &callbackstruct.CallbackBeforeCreateGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeCreateGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeCreateGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.GroupInfo.GroupID, resp.GroupID)
|
utils.NotNilReplace(&req.GroupInfo.GroupID, resp.GroupID)
|
||||||
@ -76,8 +76,8 @@ func CallbackBeforeCreateGroup(ctx context.Context, req *group.CreateGroupReq) (
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (err error) {
|
func CallbackAfterCreateGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.CreateGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackAfterCreateGroup.Enable {
|
if !globalConfig.Callback.CallbackAfterCreateGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackAfterCreateGroupReq{
|
cbReq := &callbackstruct.CallbackAfterCreateGroupReq{
|
||||||
@ -101,7 +101,7 @@ func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (e
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterCreateGroupResp{}
|
resp := &callbackstruct.CallbackAfterCreateGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterCreateGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterCreateGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -109,10 +109,11 @@ func CallbackAfterCreateGroup(ctx context.Context, req *group.CreateGroupReq) (e
|
|||||||
|
|
||||||
func CallbackBeforeMemberJoinGroup(
|
func CallbackBeforeMemberJoinGroup(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
globalConfig *config.GlobalConfig,
|
||||||
groupMember *relation.GroupMemberModel,
|
groupMember *relation.GroupMemberModel,
|
||||||
groupEx string,
|
groupEx string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeMemberJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeMemberJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
|
callbackReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{
|
||||||
@ -125,10 +126,10 @@ func CallbackBeforeMemberJoinGroup(
|
|||||||
resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{}
|
resp := &callbackstruct.CallbackBeforeMemberJoinGroupResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeMemberJoinGroup,
|
globalConfig.Callback.CallbackBeforeMemberJoinGroup,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -143,8 +144,8 @@ func CallbackBeforeMemberJoinGroup(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) {
|
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupMemberInfo) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{
|
callbackReq := callbackstruct.CallbackBeforeSetGroupMemberInfoReq{
|
||||||
@ -167,10 +168,10 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
|||||||
resp := &callbackstruct.CallbackBeforeSetGroupMemberInfoResp{}
|
resp := &callbackstruct.CallbackBeforeSetGroupMemberInfoResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeSetGroupMemberInfo,
|
globalConfig.Callback.CallbackBeforeSetGroupMemberInfo,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -189,8 +190,8 @@ func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMe
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMemberInfo) (err error) {
|
func CallbackAfterSetGroupMemberInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupMemberInfo) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupMemberInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := callbackstruct.CallbackAfterSetGroupMemberInfoReq{
|
callbackReq := callbackstruct.CallbackAfterSetGroupMemberInfoReq{
|
||||||
@ -211,14 +212,14 @@ func CallbackAfterSetGroupMemberInfo(ctx context.Context, req *group.SetGroupMem
|
|||||||
callbackReq.Ex = &req.Ex.Value
|
callbackReq.Ex = &req.Ex.Value
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterSetGroupMemberInfoResp{}
|
resp := &callbackstruct.CallbackAfterSetGroupMemberInfoResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupMemberInfo); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterSetGroupMemberInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackQuitGroup(ctx context.Context, req *group.QuitGroupReq) (err error) {
|
func CallbackQuitGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.QuitGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackQuitGroup.Enable {
|
if !globalConfig.Callback.CallbackQuitGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackQuitGroupReq{
|
cbReq := &callbackstruct.CallbackQuitGroupReq{
|
||||||
@ -227,14 +228,14 @@ func CallbackQuitGroup(ctx context.Context, req *group.QuitGroupReq) (err error)
|
|||||||
UserID: req.UserID,
|
UserID: req.UserID,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackQuitGroupResp{}
|
resp := &callbackstruct.CallbackQuitGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackKillGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberReq) (err error) {
|
func CallbackKillGroupMember(ctx context.Context, globalConfig *config.GlobalConfig, req *pbgroup.KickGroupMemberReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackKillGroupMember.Enable {
|
if !globalConfig.Callback.CallbackKillGroupMember.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &callbackstruct.CallbackKillGroupMemberReq{
|
cbReq := &callbackstruct.CallbackKillGroupMemberReq{
|
||||||
@ -243,41 +244,41 @@ func CallbackKillGroupMember(ctx context.Context, req *pbgroup.KickGroupMemberRe
|
|||||||
KickedUserIDs: req.KickedUserIDs,
|
KickedUserIDs: req.KickedUserIDs,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackKillGroupMemberResp{}
|
resp := &callbackstruct.CallbackKillGroupMemberResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackDismissGroup(ctx context.Context, req *callbackstruct.CallbackDisMissGroupReq) (err error) {
|
func CallbackDismissGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *callbackstruct.CallbackDisMissGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackDismissGroup.Enable {
|
if !globalConfig.Callback.CallbackDismissGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = callbackstruct.CallbackDisMissGroupCommand
|
req.CallbackCommand = callbackstruct.CallbackDisMissGroupCommand
|
||||||
resp := &callbackstruct.CallbackDisMissGroupResp{}
|
resp := &callbackstruct.CallbackDisMissGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackQuitGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackQuitGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackApplyJoinGroupBefore(ctx context.Context, req *callbackstruct.CallbackJoinGroupReq) (err error) {
|
func CallbackApplyJoinGroupBefore(ctx context.Context, globalConfig *config.GlobalConfig, req *callbackstruct.CallbackJoinGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
req.CallbackCommand = callbackstruct.CallbackBeforeJoinGroupCommand
|
req.CallbackCommand = callbackstruct.CallbackBeforeJoinGroupCommand
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackJoinGroupResp{}
|
resp := &callbackstruct.CallbackJoinGroupResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeJoinGroup); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeJoinGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
func CallbackAfterTransferGroupOwner(ctx context.Context, globalConfig *config.GlobalConfig, req *pbgroup.TransferGroupOwnerReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackAfterTransferGroupOwner.Enable {
|
if !globalConfig.Callback.CallbackAfterTransferGroupOwner.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,13 +290,13 @@ func CallbackAfterTransferGroupOwner(ctx context.Context, req *pbgroup.TransferG
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
resp := &callbackstruct.CallbackTransferGroupOwnerResp{}
|
||||||
if err = http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterTransferGroupOwner); err != nil {
|
if err = http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterTransferGroupOwner); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserToGroupReq) (err error) {
|
func CallbackBeforeInviteUserToGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.InviteUserToGroupReq) (err error) {
|
||||||
if !config.Config.Callback.CallbackBeforeInviteUserToGroup.Enable {
|
if !globalConfig.Callback.CallbackBeforeInviteUserToGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,10 +311,10 @@ func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserT
|
|||||||
resp := &callbackstruct.CallbackBeforeInviteUserToGroupResp{}
|
resp := &callbackstruct.CallbackBeforeInviteUserToGroupResp{}
|
||||||
err = http.CallBackPostReturn(
|
err = http.CallBackPostReturn(
|
||||||
ctx,
|
ctx,
|
||||||
config.Config.Callback.CallbackUrl,
|
globalConfig.Callback.CallbackUrl,
|
||||||
callbackReq,
|
callbackReq,
|
||||||
resp,
|
resp,
|
||||||
config.Config.Callback.CallbackBeforeInviteUserToGroup,
|
globalConfig.Callback.CallbackBeforeInviteUserToGroup,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -327,8 +328,8 @@ func CallbackBeforeInviteUserToGroup(ctx context.Context, req *group.InviteUserT
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterJoinGroup(ctx context.Context, req *group.JoinGroupReq) error {
|
func CallbackAfterJoinGroup(ctx context.Context, globalConfig *config.GlobalConfig, req *group.JoinGroupReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterJoinGroup.Enable {
|
if !globalConfig.Callback.CallbackAfterJoinGroup.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackAfterJoinGroupReq{
|
callbackReq := &callbackstruct.CallbackAfterJoinGroupReq{
|
||||||
@ -340,14 +341,14 @@ func CallbackAfterJoinGroup(ctx context.Context, req *group.JoinGroupReq) error
|
|||||||
InviterUserID: req.InviterUserID,
|
InviterUserID: req.InviterUserID,
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterJoinGroupResp{}
|
resp := &callbackstruct.CallbackAfterJoinGroupResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterJoinGroup); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterJoinGroup); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
func CallbackBeforeSetGroupInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSetGroupInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeSetGroupInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackBeforeSetGroupInfoReq{
|
callbackReq := &callbackstruct.CallbackBeforeSetGroupInfoReq{
|
||||||
@ -374,7 +375,7 @@ func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackBeforeSetGroupInfoResp{}
|
resp := &callbackstruct.CallbackBeforeSetGroupInfoResp{}
|
||||||
|
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackBeforeSetGroupInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackBeforeSetGroupInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,8 +397,8 @@ func CallbackBeforeSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
utils.NotNilReplace(&req.GroupInfoForSet.Introduction, &resp.Introduction)
|
utils.NotNilReplace(&req.GroupInfoForSet.Introduction, &resp.Introduction)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq) error {
|
func CallbackAfterSetGroupInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *group.SetGroupInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSetGroupInfo.Enable {
|
if !globalConfig.Callback.CallbackAfterSetGroupInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &callbackstruct.CallbackAfterSetGroupInfoReq{
|
callbackReq := &callbackstruct.CallbackAfterSetGroupInfoReq{
|
||||||
@ -421,7 +422,7 @@ func CallbackAfterSetGroupInfo(ctx context.Context, req *group.SetGroupInfoReq)
|
|||||||
callbackReq.ApplyMemberFriend = &req.GroupInfoForSet.ApplyMemberFriend.Value
|
callbackReq.ApplyMemberFriend = &req.GroupInfoForSet.ApplyMemberFriend.Value
|
||||||
}
|
}
|
||||||
resp := &callbackstruct.CallbackAfterSetGroupInfoResp{}
|
resp := &callbackstruct.CallbackAfterSetGroupInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterSetGroupInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterSetGroupInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -17,6 +17,7 @@ package group
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -50,35 +51,35 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
|
conversationRpcClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
var gs groupServer
|
var gs groupServer
|
||||||
database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx.NewMongo(mongo.GetClient()), grouphash.NewGroupHashFromGroupServer(&gs))
|
database := controller.NewGroupDatabase(rdb, groupDB, groupMemberDB, groupRequestDB, tx.NewMongo(mongo.GetClient()), grouphash.NewGroupHashFromGroupServer(&gs))
|
||||||
gs.db = database
|
gs.db = database
|
||||||
gs.User = userRpcClient
|
gs.User = userRpcClient
|
||||||
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
gs.Notification = notification.NewGroupNotificationSender(database, &msgRpcClient, &userRpcClient, config, func(ctx context.Context, userIDs []string) ([]notification.CommonUser, error) {
|
||||||
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
users, err := userRpcClient.GetUsersInfo(ctx, userIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -87,6 +88,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
})
|
})
|
||||||
gs.conversationRpcClient = conversationRpcClient
|
gs.conversationRpcClient = conversationRpcClient
|
||||||
gs.msgRpcClient = msgRpcClient
|
gs.msgRpcClient = msgRpcClient
|
||||||
|
gs.config = config
|
||||||
pbgroup.RegisterGroupServer(server, &gs)
|
pbgroup.RegisterGroupServer(server, &gs)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -97,6 +99,7 @@ type groupServer struct {
|
|||||||
Notification *notification.GroupNotificationSender
|
Notification *notification.GroupNotificationSender
|
||||||
conversationRpcClient rpcclient.ConversationRpcClient
|
conversationRpcClient rpcclient.ConversationRpcClient
|
||||||
msgRpcClient rpcclient.MessageRpcClient
|
msgRpcClient rpcclient.MessageRpcClient
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoinedGroupIDsReq) (*pbgroup.GetJoinedGroupIDsResp, error) {
|
func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoinedGroupIDsReq) (*pbgroup.GetJoinedGroupIDsResp, error) {
|
||||||
@ -105,7 +108,6 @@ func (s *groupServer) GetJoinedGroupIDs(ctx context.Context, req *pbgroup.GetJoi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) {
|
func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgroup.NotificationUserInfoUpdateReq) (*pbgroup.NotificationUserInfoUpdateResp, error) {
|
||||||
defer log.ZDebug(ctx, "NotificationUserInfoUpdate return")
|
|
||||||
members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID)
|
members, err := s.db.FindGroupMemberUser(ctx, nil, req.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -117,7 +119,6 @@ func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgro
|
|||||||
}
|
}
|
||||||
groupIDs = append(groupIDs, member.GroupID)
|
groupIDs = append(groupIDs, member.GroupID)
|
||||||
}
|
}
|
||||||
log.ZInfo(ctx, "NotificationUserInfoUpdate", "joinGroupNum", len(members), "updateNum", len(groupIDs), "updateGroupIDs", groupIDs)
|
|
||||||
for _, groupID := range groupIDs {
|
for _, groupID := range groupIDs {
|
||||||
if err := s.Notification.GroupMemberInfoSetNotification(ctx, groupID, req.UserID); err != nil {
|
if err := s.Notification.GroupMemberInfoSetNotification(ctx, groupID, req.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate setGroupMemberInfo notification failed", err, "groupID", groupID)
|
log.ZError(ctx, "NotificationUserInfoUpdate setGroupMemberInfo notification failed", err, "groupID", groupID)
|
||||||
@ -131,7 +132,7 @@ func (s *groupServer) NotificationUserInfoUpdate(ctx context.Context, req *pbgro
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error {
|
func (s *groupServer) CheckGroupAdmin(ctx context.Context, groupID string) error {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
groupMember, err := s.db.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx))
|
groupMember, err := s.db.TakeGroupMember(ctx, groupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -196,7 +197,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
if req.OwnerUserID == "" {
|
if req.OwnerUserID == "" {
|
||||||
return nil, errs.ErrArgs.Wrap("no group owner")
|
return nil, errs.ErrArgs.Wrap("no group owner")
|
||||||
}
|
}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userIDs := append(append(req.MemberUserIDs, req.AdminUserIDs...), req.OwnerUserID)
|
userIDs := append(append(req.MemberUserIDs, req.AdminUserIDs...), req.OwnerUserID)
|
||||||
@ -215,7 +216,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
return nil, errs.ErrUserIDNotFound.Wrap("user not found")
|
return nil, errs.ErrUserIDNotFound.Wrap("user not found")
|
||||||
}
|
}
|
||||||
// Callback Before create Group
|
// Callback Before create Group
|
||||||
if err := CallbackBeforeCreateGroup(ctx, req); err != nil {
|
if err := CallbackBeforeCreateGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var groupMembers []*relationtb.GroupMemberModel
|
var groupMembers []*relationtb.GroupMemberModel
|
||||||
@ -234,7 +235,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, groupMember, group.Ex); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
groupMembers = append(groupMembers, groupMember)
|
groupMembers = append(groupMembers, groupMember)
|
||||||
@ -302,7 +303,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
AdminUserIDs: req.AdminUserIDs,
|
AdminUserIDs: req.AdminUserIDs,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterCreateGroup(ctx, reqCallBackAfter); err != nil {
|
if err := CallbackAfterCreateGroup(ctx, s.config, reqCallBackAfter); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +312,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR
|
|||||||
|
|
||||||
func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJoinedGroupListReq) (*pbgroup.GetJoinedGroupListResp, error) {
|
func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJoinedGroupListReq) (*pbgroup.GetJoinedGroupListResp, error) {
|
||||||
resp := &pbgroup.GetJoinedGroupListResp{}
|
resp := &pbgroup.GetJoinedGroupListResp{}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.FromUserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.FromUserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
total, members, err := s.db.PageGetJoinGroup(ctx, req.FromUserID, req.Pagination)
|
total, members, err := s.db.PageGetJoinGroup(ctx, req.FromUserID, req.Pagination)
|
||||||
@ -381,7 +382,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
}
|
}
|
||||||
var groupMember *relationtb.GroupMemberModel
|
var groupMember *relationtb.GroupMemberModel
|
||||||
var opUserID string
|
var opUserID string
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opUserID = mcontext.GetOpUserID(ctx)
|
opUserID = mcontext.GetOpUserID(ctx)
|
||||||
var err error
|
var err error
|
||||||
groupMember, err = s.db.TakeGroupMember(ctx, req.GroupID, opUserID)
|
groupMember, err = s.db.TakeGroupMember(ctx, req.GroupID, opUserID)
|
||||||
@ -393,11 +394,11 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackBeforeInviteUserToGroup(ctx, req); err != nil {
|
if err := CallbackBeforeInviteUserToGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if group.NeedVerification == constant.AllNeedVerification {
|
if group.NeedVerification == constant.AllNeedVerification {
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) {
|
if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) {
|
||||||
var requests []*relationtb.GroupRequestModel
|
var requests []*relationtb.GroupRequestModel
|
||||||
for _, userID := range req.InvitedUserIDs {
|
for _, userID := range req.InvitedUserIDs {
|
||||||
@ -437,7 +438,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, member, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupMembers = append(groupMembers, member)
|
groupMembers = append(groupMembers, member)
|
||||||
@ -537,7 +538,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou
|
|||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
memberMap[member.UserID] = members[i]
|
memberMap[member.UserID] = members[i]
|
||||||
}
|
}
|
||||||
isAppManagerUid := authverify.IsAppManagerUid(ctx)
|
isAppManagerUid := authverify.IsAppManagerUid(ctx, s.config)
|
||||||
opMember := memberMap[opUserID]
|
opMember := memberMap[opUserID]
|
||||||
for _, userID := range req.KickedUserIDs {
|
for _, userID := range req.KickedUserIDs {
|
||||||
member, ok := memberMap[userID]
|
member, ok := memberMap[userID]
|
||||||
@ -609,7 +610,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackKillGroupMember(ctx, req); err != nil {
|
if err := CallbackKillGroupMember(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -735,7 +736,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
if !utils.Contain(req.HandleResult, constant.GroupResponseAgree, constant.GroupResponseRefuse) {
|
if !utils.Contain(req.HandleResult, constant.GroupResponseAgree, constant.GroupResponseRefuse) {
|
||||||
return nil, errs.ErrArgs.Wrap("HandleResult unknown")
|
return nil, errs.ErrArgs.Wrap("HandleResult unknown")
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
groupMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
groupMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -779,7 +780,7 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup
|
|||||||
OperatorUserID: mcontext.GetOpUserID(ctx),
|
OperatorUserID: mcontext.GetOpUserID(ctx),
|
||||||
Ex: groupRequest.Ex,
|
Ex: groupRequest.Ex,
|
||||||
}
|
}
|
||||||
if err = CallbackBeforeMemberJoinGroup(ctx, member, group.Ex); err != nil {
|
if err = CallbackBeforeMemberJoinGroup(ctx, s.config, member, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -827,7 +828,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CallbackApplyJoinGroupBefore(ctx, reqCall); err != nil {
|
if err = CallbackApplyJoinGroupBefore(ctx, s.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = s.db.TakeGroupMember(ctx, req.GroupID, req.InviterUserID)
|
_, err = s.db.TakeGroupMember(ctx, req.GroupID, req.InviterUserID)
|
||||||
@ -848,7 +849,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
JoinTime: time.Now(),
|
JoinTime: time.Now(),
|
||||||
MuteEndTime: time.UnixMilli(0),
|
MuteEndTime: time.UnixMilli(0),
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeMemberJoinGroup(ctx, groupMember, group.Ex); err != nil {
|
if err := CallbackBeforeMemberJoinGroup(ctx, s.config, groupMember, group.Ex); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil {
|
if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil {
|
||||||
@ -859,7 +860,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
s.Notification.MemberEnterNotification(ctx, req.GroupID, req.InviterUserID)
|
||||||
if err = CallbackAfterJoinGroup(ctx, req); err != nil {
|
if err = CallbackAfterJoinGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -873,7 +874,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq)
|
|||||||
HandledTime: time.Unix(0, 0),
|
HandledTime: time.Unix(0, 0),
|
||||||
Ex: req.Ex,
|
Ex: req.Ex,
|
||||||
}
|
}
|
||||||
if err := s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil {
|
if err = s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.JoinGroupApplicationNotification(ctx, req)
|
s.Notification.JoinGroupApplicationNotification(ctx, req)
|
||||||
@ -885,7 +886,7 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq)
|
|||||||
if req.UserID == "" {
|
if req.UserID == "" {
|
||||||
req.UserID = mcontext.GetOpUserID(ctx)
|
req.UserID = mcontext.GetOpUserID(ctx)
|
||||||
} else {
|
} else {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -909,7 +910,7 @@ func (s *groupServer) QuitGroup(ctx context.Context, req *pbgroup.QuitGroupReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// callback
|
// callback
|
||||||
if err := CallbackQuitGroup(ctx, req); err != nil {
|
if err := CallbackQuitGroup(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -926,7 +927,7 @@ func (s *groupServer) deleteMemberAndSetConversationSeq(ctx context.Context, gro
|
|||||||
|
|
||||||
func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) {
|
func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) {
|
||||||
var opMember *relationtb.GroupMemberModel
|
var opMember *relationtb.GroupMemberModel
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
var err error
|
var err error
|
||||||
opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -939,7 +940,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeSetGroupInfo(ctx, req); err != nil {
|
if err := CallbackBeforeSetGroupInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
group, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID)
|
group, err := s.db.TakeGroup(ctx, req.GroupInfoForSet.GroupID)
|
||||||
@ -1008,7 +1009,7 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInf
|
|||||||
if num > 0 {
|
if num > 0 {
|
||||||
_ = s.Notification.GroupInfoSetNotification(ctx, tips)
|
_ = s.Notification.GroupInfoSetNotification(ctx, tips)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterSetGroupInfo(ctx, req); err != nil {
|
if err := CallbackAfterSetGroupInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -1045,7 +1046,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||||||
if newOwner == nil {
|
if newOwner == nil {
|
||||||
return nil, errs.ErrArgs.Wrap("NewOwnerUser not in group " + req.NewOwnerUserID)
|
return nil, errs.ErrArgs.Wrap("NewOwnerUser not in group " + req.NewOwnerUserID)
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if !(mcontext.GetOpUserID(ctx) == oldOwner.UserID && oldOwner.RoleLevel == constant.GroupOwner) {
|
if !(mcontext.GetOpUserID(ctx) == oldOwner.UserID && oldOwner.RoleLevel == constant.GroupOwner) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("no permission transfer group owner")
|
return nil, errs.ErrNoPermission.Wrap("no permission transfer group owner")
|
||||||
}
|
}
|
||||||
@ -1054,7 +1055,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterTransferGroupOwner(ctx, req); err != nil {
|
if err := CallbackAfterTransferGroupOwner(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
s.Notification.GroupOwnerTransferredNotification(ctx, req)
|
||||||
@ -1186,7 +1187,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
if owner.UserID != mcontext.GetOpUserID(ctx) {
|
if owner.UserID != mcontext.GetOpUserID(ctx) {
|
||||||
return nil, errs.ErrNoPermission.Wrap("not group owner")
|
return nil, errs.ErrNoPermission.Wrap("not group owner")
|
||||||
}
|
}
|
||||||
@ -1228,7 +1229,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbgroup.DismissGrou
|
|||||||
MembersID: membersID,
|
MembersID: membersID,
|
||||||
GroupType: string(group.GroupType),
|
GroupType: string(group.GroupType),
|
||||||
}
|
}
|
||||||
if err := CallbackDismissGroup(ctx, reqCall); err != nil {
|
if err := CallbackDismissGroup(ctx, s.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,7 +1245,7 @@ func (s *groupServer) MuteGroupMember(ctx context.Context, req *pbgroup.MuteGrou
|
|||||||
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1278,7 +1279,7 @@ func (s *groupServer) CancelMuteGroupMember(ctx context.Context, req *pbgroup.Ca
|
|||||||
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
if err := s.PopulateGroupMember(ctx, member); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, s.config) {
|
||||||
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
opMember, err := s.db.TakeGroupMember(ctx, req.GroupID, mcontext.GetOpUserID(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1337,7 +1338,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
if opUserID == "" {
|
if opUserID == "" {
|
||||||
return nil, errs.ErrNoPermission.Wrap("no op user id")
|
return nil, errs.ErrNoPermission.Wrap("no op user id")
|
||||||
}
|
}
|
||||||
isAppManagerUid := authverify.IsAppManagerUid(ctx)
|
isAppManagerUid := authverify.IsAppManagerUid(ctx, s.config)
|
||||||
for i := range req.Members {
|
for i := range req.Members {
|
||||||
req.Members[i].FaceURL = nil
|
req.Members[i].FaceURL = nil
|
||||||
}
|
}
|
||||||
@ -1420,7 +1421,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(req.Members); i++ {
|
for i := 0; i < len(req.Members); i++ {
|
||||||
if err := CallbackBeforeSetGroupMemberInfo(ctx, req.Members[i]); err != nil {
|
if err := CallbackBeforeSetGroupMemberInfo(ctx, s.config, req.Members[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1447,7 +1448,7 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := 0; i < len(req.Members); i++ {
|
for i := 0; i < len(req.Members); i++ {
|
||||||
if err := CallbackAfterSetGroupMemberInfo(ctx, req.Members[i]); err != nil {
|
if err := CallbackAfterSetGroupMemberInfo(ctx, s.config, req.Members[i]); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ func (m *msgServer) MarkMsgsAsRead(
|
|||||||
Seqs: req.Seqs,
|
Seqs: req.Seqs,
|
||||||
ContentType: conversation.ConversationType,
|
ContentType: conversation.ConversationType,
|
||||||
}
|
}
|
||||||
if err = CallbackSingleMsgRead(ctx, req_callback); err != nil {
|
if err = CallbackSingleMsgRead(ctx, m.config, req_callback); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ func (m *msgServer) MarkConversationAsRead(
|
|||||||
UnreadMsgNum: req.HasReadSeq,
|
UnreadMsgNum: req.HasReadSeq,
|
||||||
ContentType: int64(conversation.ConversationType),
|
ContentType: int64(conversation.ConversationType),
|
||||||
}
|
}
|
||||||
if err := CallbackGroupMsgRead(ctx, reqCall); err != nil {
|
if err := CallbackGroupMsgRead(ctx, m.config, reqCall); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,6 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cbURL() string {
|
|
||||||
return config.Config.Callback.CallbackUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
func toCommonCallback(ctx context.Context, msg *pbchat.SendMsgReq, command string) cbapi.CommonCallbackReq {
|
func toCommonCallback(ctx context.Context, msg *pbchat.SendMsgReq, command string) cbapi.CommonCallbackReq {
|
||||||
return cbapi.CommonCallbackReq{
|
return cbapi.CommonCallbackReq{
|
||||||
SendID: msg.MsgData.SendID,
|
SendID: msg.MsgData.SendID,
|
||||||
@ -66,8 +62,8 @@ func GetContent(msg *sdkws.MsgData) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendSingleMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackBeforeSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
req := &cbapi.CallbackBeforeSendSingleMsgReq{
|
||||||
@ -75,14 +71,14 @@ func callbackBeforeSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) er
|
|||||||
RecvID: msg.MsgData.RecvID,
|
RecvID: msg.MsgData.RecvID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
|
resp := &cbapi.CallbackBeforeSendSingleMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendSingleMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeSendSingleMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendSingleMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackAfterSendSingleMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
req := &cbapi.CallbackAfterSendSingleMsgReq{
|
||||||
@ -90,14 +86,14 @@ func callbackAfterSendSingleMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
RecvID: msg.MsgData.RecvID,
|
RecvID: msg.MsgData.RecvID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
|
resp := &cbapi.CallbackAfterSendSingleMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendSingleMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackAfterSendSingleMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackBeforeSendGroupMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackBeforeSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
req := &cbapi.CallbackBeforeSendGroupMsgReq{
|
||||||
@ -105,14 +101,14 @@ func callbackBeforeSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) err
|
|||||||
GroupID: msg.MsgData.GroupID,
|
GroupID: msg.MsgData.GroupID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
|
resp := &cbapi.CallbackBeforeSendGroupMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackBeforeSendGroupMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackBeforeSendGroupMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackAfterSendGroupMsg(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
if !globalConfig.Callback.CallbackAfterSendGroupMsg.Enable || msg.MsgData.ContentType == constant.Typing {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
req := &cbapi.CallbackAfterSendGroupMsgReq{
|
||||||
@ -120,21 +116,21 @@ func callbackAfterSendGroupMsg(ctx context.Context, msg *pbchat.SendMsgReq) erro
|
|||||||
GroupID: msg.MsgData.GroupID,
|
GroupID: msg.MsgData.GroupID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
|
resp := &cbapi.CallbackAfterSendGroupMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackAfterSendGroupMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackAfterSendGroupMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
func callbackMsgModify(ctx context.Context, globalConfig *config.GlobalConfig, msg *pbchat.SendMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackMsgModify.Enable || msg.MsgData.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackMsgModify.Enable || msg.MsgData.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackMsgModifyCommandReq{
|
req := &cbapi.CallbackMsgModifyCommandReq{
|
||||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackMsgModifyCommand),
|
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackMsgModifyCommand),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackMsgModifyCommandResp{}
|
resp := &cbapi.CallbackMsgModifyCommandResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if resp.Content != nil {
|
if resp.Content != nil {
|
||||||
@ -159,34 +155,34 @@ func callbackMsgModify(ctx context.Context, msg *pbchat.SendMsgReq) error {
|
|||||||
log.ZDebug(ctx, "callbackMsgModify", "msg", msg.MsgData)
|
log.ZDebug(ctx, "callbackMsgModify", "msg", msg.MsgData)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackGroupMsgRead(ctx context.Context, req *cbapi.CallbackGroupMsgReadReq) error {
|
func CallbackGroupMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackGroupMsgReadReq) error {
|
||||||
if !config.Config.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackGroupMsgRead.Enable || req.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
|
req.CallbackCommand = cbapi.CallbackGroupMsgReadCommand
|
||||||
|
|
||||||
resp := &cbapi.CallbackGroupMsgReadResp{}
|
resp := &cbapi.CallbackGroupMsgReadResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackSingleMsgRead(ctx context.Context, req *cbapi.CallbackSingleMsgReadReq) error {
|
func CallbackSingleMsgRead(ctx context.Context, globalConfig *config.GlobalConfig, req *cbapi.CallbackSingleMsgReadReq) error {
|
||||||
if !config.Config.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text {
|
if !globalConfig.Callback.CallbackSingleMsgRead.Enable || req.ContentType != constant.Text {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req.CallbackCommand = cbapi.CallbackSingleMsgRead
|
req.CallbackCommand = cbapi.CallbackSingleMsgRead
|
||||||
|
|
||||||
resp := &cbapi.CallbackSingleMsgReadResp{}
|
resp := &cbapi.CallbackSingleMsgReadResp{}
|
||||||
|
|
||||||
if err := http.CallBackPostReturn(ctx, cbURL(), req, resp, config.Config.Callback.CallbackMsgModify); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, req, resp, globalConfig.Callback.CallbackMsgModify); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterRevokeMsg(ctx context.Context, req *pbchat.RevokeMsgReq) error {
|
func CallbackAfterRevokeMsg(ctx context.Context, globalConfig *config.GlobalConfig, req *pbchat.RevokeMsgReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterRevokeMsg.Enable {
|
if !globalConfig.Callback.CallbackAfterRevokeMsg.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
callbackReq := &cbapi.CallbackAfterRevokeMsgReq{
|
callbackReq := &cbapi.CallbackAfterRevokeMsgReq{
|
||||||
@ -196,7 +192,7 @@ func CallbackAfterRevokeMsg(ctx context.Context, req *pbchat.RevokeMsgReq) error
|
|||||||
UserID: req.UserID,
|
UserID: req.UserID,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterRevokeMsgResp{}
|
resp := &cbapi.CallbackAfterRevokeMsgResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, callbackReq, resp, config.Config.Callback.CallbackAfterRevokeMsg); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, callbackReq, resp, globalConfig.Callback.CallbackAfterRevokeMsg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -45,7 +45,7 @@ func (m *msgServer) ClearConversationsMsg(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.ClearConversationsMsgReq,
|
req *msg.ClearConversationsMsgReq,
|
||||||
) (*msg.ClearConversationsMsgResp, error) {
|
) (*msg.ClearConversationsMsgResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := m.clearConversation(ctx, req.ConversationIDs, req.UserID, req.DeleteSyncOpt); err != nil {
|
if err := m.clearConversation(ctx, req.ConversationIDs, req.UserID, req.DeleteSyncOpt); err != nil {
|
||||||
@ -58,7 +58,7 @@ func (m *msgServer) UserClearAllMsg(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.UserClearAllMsgReq,
|
req *msg.UserClearAllMsgReq,
|
||||||
) (*msg.UserClearAllMsgResp, error) {
|
) (*msg.UserClearAllMsgResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
@ -73,7 +73,7 @@ func (m *msgServer) UserClearAllMsg(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsReq) (*msg.DeleteMsgsResp, error) {
|
func (m *msgServer) DeleteMsgs(ctx context.Context, req *msg.DeleteMsgsReq) (*msg.DeleteMsgsResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
isSyncSelf, isSyncOther := m.validateDeleteSyncOpt(req.DeleteSyncOpt)
|
isSyncSelf, isSyncOther := m.validateDeleteSyncOpt(req.DeleteSyncOpt)
|
||||||
@ -121,7 +121,7 @@ func (m *msgServer) DeleteMsgPhysical(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req *msg.DeleteMsgPhysicalReq,
|
req *msg.DeleteMsgPhysicalReq,
|
||||||
) (*msg.DeleteMsgPhysicalResp, error) {
|
) (*msg.DeleteMsgPhysicalResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
remainTime := utils.GetCurrentTimestampBySecond() - req.Timestamp
|
remainTime := utils.GetCurrentTimestampBySecond() - req.Timestamp
|
||||||
|
@ -24,17 +24,17 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageInterceptorFunc func(ctx context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error)
|
type MessageInterceptorFunc func(ctx context.Context, globalConfig *config.GlobalConfig, req *msg.SendMsgReq) (*sdkws.MsgData, error)
|
||||||
|
|
||||||
func MessageHasReadEnabled(_ context.Context, req *msg.SendMsgReq) (*sdkws.MsgData, error) {
|
func MessageHasReadEnabled(_ context.Context, globalConfig *config.GlobalConfig, req *msg.SendMsgReq) (*sdkws.MsgData, error) {
|
||||||
switch {
|
switch {
|
||||||
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SingleChatType:
|
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SingleChatType:
|
||||||
if !config.Config.SingleMessageHasReadReceiptEnable {
|
if !globalConfig.SingleMessageHasReadReceiptEnable {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
return req.MsgData, nil
|
return req.MsgData, nil
|
||||||
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SuperGroupChatType:
|
case req.MsgData.ContentType == constant.HasReadReceipt && req.MsgData.SessionType == constant.SuperGroupChatType:
|
||||||
if !config.Config.GroupMessageHasReadReceiptEnable {
|
if !globalConfig.GroupMessageHasReadReceiptEnable {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
return req.MsgData, nil
|
return req.MsgData, nil
|
||||||
|
@ -19,6 +19,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
@ -26,8 +28,7 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
if req.Seq < 0 {
|
if req.Seq < 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("seq is invalid")
|
return nil, errs.ErrArgs.Wrap("seq is invalid")
|
||||||
}
|
}
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
user, err := m.User.GetUserInfo(ctx, req.UserID)
|
user, err := m.User.GetUserInfo(ctx, req.UserID)
|
||||||
@ -63,10 +64,10 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
data, _ := json.Marshal(msgs[0])
|
data, _ := json.Marshal(msgs[0])
|
||||||
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
log.ZInfo(ctx, "GetMsgBySeqs", "conversationID", req.ConversationID, "seq", req.Seq, "msg", string(data))
|
||||||
var role int32
|
var role int32
|
||||||
if !authverify.IsAppManagerUid(ctx) {
|
if !authverify.IsAppManagerUid(ctx, m.config) {
|
||||||
switch msgs[0].SessionType {
|
switch msgs[0].SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
if err := authverify.CheckAccessV3(ctx, msgs[0].SendID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, msgs[0].SendID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
role = user.AppMangerLevel
|
role = user.AppMangerLevel
|
||||||
@ -110,11 +111,11 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
}
|
}
|
||||||
revokerUserID := mcontext.GetOpUserID(ctx)
|
revokerUserID := mcontext.GetOpUserID(ctx)
|
||||||
var flag bool
|
var flag bool
|
||||||
if len(config.Config.Manager.UserID) > 0 {
|
if len(m.config.Manager.UserID) > 0 {
|
||||||
flag = utils.Contain(revokerUserID, config.Config.Manager.UserID...)
|
flag = utils.Contain(revokerUserID, m.config.Manager.UserID...)
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) == 0 && len(config.Config.IMAdmin.UserID) > 0 {
|
if len(m.config.Manager.UserID) == 0 && len(m.config.IMAdmin.UserID) > 0 {
|
||||||
flag = utils.Contain(revokerUserID, config.Config.IMAdmin.UserID...)
|
flag = utils.Contain(revokerUserID, m.config.IMAdmin.UserID...)
|
||||||
}
|
}
|
||||||
tips := sdkws.RevokeMsgTips{
|
tips := sdkws.RevokeMsgTips{
|
||||||
RevokerUserID: revokerUserID,
|
RevokerUserID: revokerUserID,
|
||||||
@ -134,7 +135,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
|
|||||||
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
|
if err := m.notificationSender.NotificationWithSesstionType(ctx, req.UserID, recvID, constant.MsgRevokeNotification, msgs[0].SessionType, &tips); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = CallbackAfterRevokeMsg(ctx, req); err != nil {
|
if err = CallbackAfterRevokeMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &msg.RevokeMsgResp{}, nil
|
return &msg.RevokeMsgResp{}, nil
|
||||||
|
@ -17,6 +17,9 @@ package msg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
pbconversation "github.com/OpenIMSDK/protocol/conversation"
|
||||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||||
@ -26,14 +29,12 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, error error) {
|
func (m *msgServer) SendMsg(ctx context.Context, req *pbmsg.SendMsgReq) (resp *pbmsg.SendMsgResp, error error) {
|
||||||
resp = &pbmsg.SendMsgResp{}
|
resp = &pbmsg.SendMsgResp{}
|
||||||
if req.MsgData != nil {
|
if req.MsgData != nil {
|
||||||
flag := isMessageHasReadEnabled(req.MsgData)
|
flag := isMessageHasReadEnabled(req.MsgData, m.config)
|
||||||
if !flag {
|
if !flag {
|
||||||
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
return nil, errs.ErrMessageHasReadDisable.Wrap()
|
||||||
}
|
}
|
||||||
@ -61,11 +62,11 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||||||
prommetrics.GroupChatMsgProcessFailedCounter.Inc()
|
prommetrics.GroupChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = callbackBeforeSendGroupMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendGroupMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForGroup(req.MsgData.GroupID), req.MsgData)
|
err = m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForGroup(req.MsgData.GroupID), req.MsgData)
|
||||||
@ -75,7 +76,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
|
|||||||
if req.MsgData.ContentType == constant.AtText {
|
if req.MsgData.ContentType == constant.AtText {
|
||||||
go m.setConversationAtInfo(ctx, req.MsgData)
|
go m.setConversationAtInfo(ctx, req.MsgData)
|
||||||
}
|
}
|
||||||
if err = callbackAfterSendGroupMsg(ctx, req); err != nil {
|
if err = callbackAfterSendGroupMsg(ctx, m.config, req); err != nil {
|
||||||
log.ZWarn(ctx, "CallbackAfterSendGroupMsg", err)
|
log.ZWarn(ctx, "CallbackAfterSendGroupMsg", err)
|
||||||
}
|
}
|
||||||
prommetrics.GroupChatMsgProcessSuccessCounter.Inc()
|
prommetrics.GroupChatMsgProcessSuccessCounter.Inc()
|
||||||
@ -107,7 +108,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
|
|||||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
|
||||||
} else { //@Everyone and @other people
|
} else { //@Everyone and @other people
|
||||||
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
|
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
|
||||||
err := m.Conversation.SetConversations(ctx, atUserID, conversation)
|
err = m.Conversation.SetConversations(ctx, atUserID, conversation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
log.ZWarn(ctx, "SetConversations", err, "userID", atUserID, "conversation", conversation)
|
||||||
}
|
}
|
||||||
@ -164,18 +165,18 @@ func (m *msgServer) sendMsgSingleChat(ctx context.Context, req *pbmsg.SendMsgReq
|
|||||||
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else {
|
} else {
|
||||||
if err = callbackBeforeSendSingleMsg(ctx, req); err != nil {
|
if err = callbackBeforeSendSingleMsg(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := callbackMsgModify(ctx, req); err != nil {
|
if err := callbackMsgModify(ctx, m.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
|
if err := m.MsgDatabase.MsgToMQ(ctx, utils.GenConversationUniqueKeyForSingle(req.MsgData.SendID, req.MsgData.RecvID), req.MsgData); err != nil {
|
||||||
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
prommetrics.SingleChatMsgProcessFailedCounter.Inc()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = callbackAfterSendSingleMsg(ctx, req)
|
err = callbackAfterSendSingleMsg(ctx, m.config, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZWarn(ctx, "CallbackAfterSendSingleMsg", err, "req", req)
|
log.ZWarn(ctx, "CallbackAfterSendSingleMsg", err, "req", req)
|
||||||
}
|
}
|
||||||
|
@ -15,16 +15,20 @@
|
|||||||
package msg
|
package msg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/conversation"
|
"github.com/OpenIMSDK/protocol/conversation"
|
||||||
"github.com/OpenIMSDK/protocol/msg"
|
"github.com/OpenIMSDK/protocol/msg"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/localcache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -40,6 +44,7 @@ type (
|
|||||||
ConversationLocalCache *localcache.ConversationLocalCache
|
ConversationLocalCache *localcache.ConversationLocalCache
|
||||||
Handlers MessageInterceptorChain
|
Handlers MessageInterceptorChain
|
||||||
notificationSender *rpcclient.NotificationSender
|
notificationSender *rpcclient.NotificationSender
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,37 +52,36 @@ func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorF
|
|||||||
m.Handlers = append(m.Handlers, interceptorFunc...)
|
m.Handlers = append(m.Handlers, interceptorFunc...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// func `(*msgServer).execInterceptorHandler` is unused
|
//func (m *msgServer) execInterceptorHandler(ctx context.Context, config *config.GlobalConfig, req *msg.SendMsgReq) error {
|
||||||
// func (m *msgServer) execInterceptorHandler(ctx context.Context, req *msg.SendMsgReq) error {
|
// for _, handler := range m.Handlers {
|
||||||
// for _, handler := range m.Handlers {
|
// msgData, err := handler(ctx, config, req)
|
||||||
// msgData, err := handler(ctx, req)
|
// if err != nil {
|
||||||
// if err != nil {
|
// return err
|
||||||
// return err
|
// }
|
||||||
// }
|
// req.MsgData = msgData
|
||||||
// req.MsgData = msgData
|
// }
|
||||||
// }
|
// return nil
|
||||||
// return nil
|
//}
|
||||||
// }
|
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := mongo.CreateMsgIndex(); err != nil {
|
if err := mongo.CreateMsgIndex(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
cacheModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
|
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
conversationClient := rpcclient.NewConversationRpcClient(client)
|
conversationClient := rpcclient.NewConversationRpcClient(client, config)
|
||||||
userRpcClient := rpcclient.NewUserRpcClient(client)
|
userRpcClient := rpcclient.NewUserRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
friendRpcClient := rpcclient.NewFriendRpcClient(client, config)
|
||||||
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
|
msgDatabase, err := controller.NewCommonMsgDatabase(msgDocModel, cacheModel, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -90,8 +94,9 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
|
GroupLocalCache: localcache.NewGroupLocalCache(&groupRpcClient),
|
||||||
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
|
ConversationLocalCache: localcache.NewConversationLocalCache(&conversationClient),
|
||||||
friend: &friendRpcClient,
|
friend: &friendRpcClient,
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
s.notificationSender = rpcclient.NewNotificationSender(rpcclient.WithLocalSendMsg(s.SendMsg))
|
s.notificationSender = rpcclient.NewNotificationSender(config, rpcclient.WithLocalSendMsg(s.SendMsg))
|
||||||
s.addInterceptorHandler(MessageHasReadEnabled)
|
s.addInterceptorHandler(MessageHasReadEnabled)
|
||||||
msg.RegisterMsgServer(server, s)
|
msg.RegisterMsgServer(server, s)
|
||||||
return nil
|
return nil
|
||||||
|
@ -88,7 +88,7 @@ func (m *msgServer) PullMessageBySeqs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sdkws.GetMaxSeqResp, error) {
|
func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sdkws.GetMaxSeqResp, error) {
|
||||||
if err := authverify.CheckAccessV3(ctx, req.UserID); err != nil {
|
if err := authverify.CheckAccessV3(ctx, req.UserID, m.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
conversationIDs, err := m.ConversationLocalCache.GetConversationIDs(ctx, req.UserID)
|
||||||
|
@ -23,16 +23,16 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isMessageHasReadEnabled(msgData *sdkws.MsgData) bool {
|
func isMessageHasReadEnabled(msgData *sdkws.MsgData, config *config.GlobalConfig) bool {
|
||||||
switch {
|
switch {
|
||||||
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SingleChatType:
|
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SingleChatType:
|
||||||
if config.Config.SingleMessageHasReadReceiptEnable {
|
if config.SingleMessageHasReadReceiptEnable {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SuperGroupChatType:
|
case msgData.ContentType == constant.HasReadReceipt && msgData.SessionType == constant.SuperGroupChatType:
|
||||||
if config.Config.GroupMessageHasReadReceiptEnable {
|
if config.GroupMessageHasReadReceiptEnable {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ExcludeContentType = []int{constant.HasReadReceipt}
|
var ExcludeContentType = []int{constant.HasReadReceipt}
|
||||||
@ -50,10 +49,10 @@ type MessageRevoked struct {
|
|||||||
func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgReq) error {
|
func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgReq) error {
|
||||||
switch data.MsgData.SessionType {
|
switch data.MsgData.SessionType {
|
||||||
case constant.SingleChatType:
|
case constant.SingleChatType:
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
if len(m.config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, m.config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(data.MsgData.SendID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(data.MsgData.SendID, m.config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
||||||
@ -67,7 +66,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if black {
|
if black {
|
||||||
return errs.ErrBlockedByPeer.Wrap()
|
return errs.ErrBlockedByPeer.Wrap()
|
||||||
}
|
}
|
||||||
if *config.Config.MessageVerify.FriendVerify {
|
if *m.config.MessageVerify.FriendVerify {
|
||||||
friend, err := m.friend.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
friend, err := m.friend.IsFriend(ctx, data.MsgData.SendID, data.MsgData.RecvID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -90,10 +89,10 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
|
|||||||
if groupInfo.GroupType == constant.SuperGroup {
|
if groupInfo.GroupType == constant.SuperGroup {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, config.Config.Manager.UserID) {
|
if len(m.config.Manager.UserID) > 0 && utils.IsContain(data.MsgData.SendID, m.config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(data.MsgData.SendID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(data.MsgData.SendID, m.config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
if data.MsgData.ContentType <= constant.NotificationEnd &&
|
||||||
@ -158,9 +157,6 @@ func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
|
|||||||
case constant.Custom:
|
case constant.Custom:
|
||||||
fallthrough
|
fallthrough
|
||||||
case constant.Quote:
|
case constant.Quote:
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsConversationUpdate, true)
|
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, true)
|
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsSenderSync, true)
|
|
||||||
case constant.Revoke:
|
case constant.Revoke:
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, false)
|
utils.SetSwitchFromOptions(msg.Options, constant.IsUnreadCount, false)
|
||||||
utils.SetSwitchFromOptions(msg.Options, constant.IsOfflinePush, false)
|
utils.SetSwitchFromOptions(msg.Options, constant.IsOfflinePush, false)
|
||||||
|
@ -82,7 +82,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) (*third.DeleteLogsResp, error) {
|
func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) (*third.DeleteLogsResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, t.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userID := ""
|
userID := ""
|
||||||
@ -123,7 +123,7 @@ func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) (*third.SearchLogsResp, error) {
|
func (t *thirdServer) SearchLogs(ctx context.Context, req *third.SearchLogsReq) (*third.SearchLogsResp, error) {
|
||||||
if err := authverify.CheckAdmin(ctx); err != nil {
|
if err := authverify.CheckAdmin(ctx, t.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
|
@ -29,7 +29,6 @@ import (
|
|||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cont"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cont"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
@ -54,7 +53,7 @@ func (t *thirdServer) PartSize(ctx context.Context, req *third.PartSizeReq) (*th
|
|||||||
|
|
||||||
func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.InitiateMultipartUploadReq) (*third.InitiateMultipartUploadResp, error) {
|
func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.InitiateMultipartUploadReq) (*third.InitiateMultipartUploadResp, error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
defer log.ZDebug(ctx, "return")
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
expireTime := time.Now().Add(t.defaultExpire)
|
expireTime := time.Now().Add(t.defaultExpire)
|
||||||
@ -133,7 +132,7 @@ func (t *thirdServer) AuthSign(ctx context.Context, req *third.AuthSignReq) (*th
|
|||||||
|
|
||||||
func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.CompleteMultipartUploadReq) (*third.CompleteMultipartUploadResp, error) {
|
func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.CompleteMultipartUploadReq) (*third.CompleteMultipartUploadResp, error) {
|
||||||
defer log.ZDebug(ctx, "return")
|
defer log.ZDebug(ctx, "return")
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result, err := t.s3dataBase.CompleteMultipartUpload(ctx, req.UploadID, req.Parts)
|
result, err := t.s3dataBase.CompleteMultipartUpload(ctx, req.UploadID, req.Parts)
|
||||||
@ -190,13 +189,13 @@ func (t *thirdServer) InitiateFormData(ctx context.Context, req *third.InitiateF
|
|||||||
if req.Size <= 0 {
|
if req.Size <= 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("size must be greater than 0")
|
return nil, errs.ErrArgs.Wrap("size must be greater than 0")
|
||||||
}
|
}
|
||||||
if err := checkUploadName(ctx, req.Name); err != nil {
|
if err := t.checkUploadName(ctx, req.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var duration time.Duration
|
var duration time.Duration
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
var key string
|
var key string
|
||||||
if authverify.IsManagerUserID(opUserID) {
|
if t.IsManagerUserID(opUserID) {
|
||||||
if req.Millisecond <= 0 {
|
if req.Millisecond <= 0 {
|
||||||
duration = time.Minute * 10
|
duration = time.Minute * 10
|
||||||
} else {
|
} else {
|
||||||
@ -256,7 +255,7 @@ func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.CompleteF
|
|||||||
if err := json.Unmarshal(data, &mate); err != nil {
|
if err := json.Unmarshal(data, &mate); err != nil {
|
||||||
return nil, errs.ErrArgs.Wrap("invalid id " + err.Error())
|
return nil, errs.ErrArgs.Wrap("invalid id " + err.Error())
|
||||||
}
|
}
|
||||||
if err := checkUploadName(ctx, mate.Name); err != nil {
|
if err := t.checkUploadName(ctx, mate.Name); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
info, err := t.s3dataBase.StatObject(ctx, mate.Key)
|
info, err := t.s3dataBase.StatObject(ctx, mate.Key)
|
||||||
|
@ -20,59 +20,63 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/cos"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/minio"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3/oss"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
logdb, err := mgo.NewLogMongo(mongo.GetDatabase())
|
logdb, err := mgo.NewLogMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase())
|
s3db, err := mgo.NewS3Mongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
apiURL := config.Config.Object.ApiURL
|
apiURL := config.Object.ApiURL
|
||||||
if apiURL == "" {
|
if apiURL == "" {
|
||||||
return fmt.Errorf("api url is empty")
|
return fmt.Errorf("api url is empty")
|
||||||
}
|
}
|
||||||
if _, err := url.Parse(config.Config.Object.ApiURL); err != nil {
|
if _, parseErr := url.Parse(config.Object.ApiURL); parseErr != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if apiURL[len(apiURL)-1] != '/' {
|
if apiURL[len(apiURL)-1] != '/' {
|
||||||
apiURL += "/"
|
apiURL += "/"
|
||||||
}
|
}
|
||||||
apiURL += "object/"
|
apiURL += "object/"
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Select based on the configuration file strategy
|
// 根据配置文件策略选择 oss 方式
|
||||||
enable := config.Config.Object.Enable
|
enable := config.Object.Enable
|
||||||
var o s3.Interface
|
var o s3.Interface
|
||||||
switch config.Config.Object.Enable {
|
switch enable {
|
||||||
case "minio":
|
case "minio":
|
||||||
o, err = minio.NewMinio(cache.NewMinioCache(rdb))
|
o, err = minio.NewMinio(cache.NewMinioCache(rdb), minio.Config(config.Object.Minio))
|
||||||
case "cos":
|
case "cos":
|
||||||
o, err = cos.NewCos()
|
o, err = cos.NewCos(cos.Config(config.Object.Cos))
|
||||||
case "oss":
|
case "oss":
|
||||||
o, err = oss.NewOSS()
|
o, err = oss.NewOSS(oss.Config(config.Object.Oss))
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid object enable: %s", enable)
|
err = fmt.Errorf("invalid object enable: %s", enable)
|
||||||
}
|
}
|
||||||
@ -81,10 +85,11 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
|
|||||||
}
|
}
|
||||||
third.RegisterThirdServer(server, &thirdServer{
|
third.RegisterThirdServer(server, &thirdServer{
|
||||||
apiURL: apiURL,
|
apiURL: apiURL,
|
||||||
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb), logdb),
|
thirdDatabase: controller.NewThirdDatabase(cache.NewMsgCacheModel(rdb, config), logdb),
|
||||||
userRpcClient: rpcclient.NewUserRpcClient(client),
|
userRpcClient: rpcclient.NewUserRpcClient(client, config),
|
||||||
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
s3dataBase: controller.NewS3Database(rdb, o, s3db),
|
||||||
defaultExpire: time.Hour * 24 * 7,
|
defaultExpire: time.Hour * 24 * 7,
|
||||||
|
config: config,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -95,6 +100,7 @@ type thirdServer struct {
|
|||||||
s3dataBase controller.S3Database
|
s3dataBase controller.S3Database
|
||||||
userRpcClient rpcclient.UserRpcClient
|
userRpcClient rpcclient.UserRpcClient
|
||||||
defaultExpire time.Duration
|
defaultExpire time.Duration
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) {
|
func (t *thirdServer) FcmUpdateToken(ctx context.Context, req *third.FcmUpdateTokenReq) (resp *third.FcmUpdateTokenResp, err error) {
|
||||||
|
@ -21,10 +21,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/third"
|
"github.com/OpenIMSDK/protocol/third"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
||||||
@ -41,7 +42,7 @@ func toPbMapArray(m map[string][]string) []*third.KeyValues {
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkUploadName(ctx context.Context, name string) error {
|
func (t *thirdServer) checkUploadName(ctx context.Context, name string) error {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return errs.ErrArgs.Wrap("name is empty")
|
return errs.ErrArgs.Wrap("name is empty")
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ func checkUploadName(ctx context.Context, name string) error {
|
|||||||
if opUserID == "" {
|
if opUserID == "" {
|
||||||
return errs.ErrNoPermission.Wrap("opUserID is empty")
|
return errs.ErrNoPermission.Wrap("opUserID is empty")
|
||||||
}
|
}
|
||||||
if !authverify.IsManagerUserID(opUserID) {
|
if !authverify.IsManagerUserID(opUserID, t.config) {
|
||||||
if !strings.HasPrefix(name, opUserID+"/") {
|
if !strings.HasPrefix(name, opUserID+"/") {
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("name must start with `%s/`", opUserID))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("name must start with `%s/`", opUserID))
|
||||||
}
|
}
|
||||||
@ -79,3 +80,7 @@ func checkValidObjectName(objectName string) error {
|
|||||||
}
|
}
|
||||||
return checkValidObjectNamePrefix(objectName)
|
return checkValidObjectNamePrefix(objectName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *thirdServer) IsManagerUserID(opUserID string) bool {
|
||||||
|
return authverify.IsManagerUserID(opUserID, t.config)
|
||||||
|
}
|
||||||
|
@ -24,8 +24,8 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) error {
|
func CallbackBeforeUpdateUserInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUpdateUserInfo.Enable {
|
if !globalConfig.Callback.CallbackBeforeUpdateUserInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUpdateUserInfoReq{
|
cbReq := &cbapi.CallbackBeforeUpdateUserInfoReq{
|
||||||
@ -35,7 +35,7 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
|||||||
Nickname: &req.UserInfo.Nickname,
|
Nickname: &req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeUpdateUserInfoResp{}
|
resp := &cbapi.CallbackBeforeUpdateUserInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(&req.UserInfo.FaceURL, resp.FaceURL)
|
utils.NotNilReplace(&req.UserInfo.FaceURL, resp.FaceURL)
|
||||||
@ -43,8 +43,8 @@ func CallbackBeforeUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInf
|
|||||||
utils.NotNilReplace(&req.UserInfo.Nickname, resp.Nickname)
|
utils.NotNilReplace(&req.UserInfo.Nickname, resp.Nickname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) error {
|
func CallbackAfterUpdateUserInfo(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUpdateUserInfo.Enable {
|
if !globalConfig.Callback.CallbackAfterUpdateUserInfo.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUpdateUserInfoReq{
|
cbReq := &cbapi.CallbackAfterUpdateUserInfoReq{
|
||||||
@ -54,13 +54,13 @@ func CallbackAfterUpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfo
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterUpdateUserInfoResp{}
|
resp := &cbapi.CallbackAfterUpdateUserInfoResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) error {
|
func CallbackBeforeUpdateUserInfoEx(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoExReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUpdateUserInfoEx.Enable {
|
if !globalConfig.Callback.CallbackBeforeUpdateUserInfoEx.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUpdateUserInfoExReq{
|
cbReq := &cbapi.CallbackBeforeUpdateUserInfoExReq{
|
||||||
@ -70,7 +70,7 @@ func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforeUpdateUserInfoExResp{}
|
resp := &cbapi.CallbackBeforeUpdateUserInfoExResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
utils.NotNilReplace(req.UserInfo.FaceURL, resp.FaceURL)
|
utils.NotNilReplace(req.UserInfo.FaceURL, resp.FaceURL)
|
||||||
@ -78,8 +78,8 @@ func CallbackBeforeUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
utils.NotNilReplace(req.UserInfo.Nickname, resp.Nickname)
|
utils.NotNilReplace(req.UserInfo.Nickname, resp.Nickname)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func CallbackAfterUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) error {
|
func CallbackAfterUpdateUserInfoEx(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UpdateUserInfoExReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUpdateUserInfoEx.Enable {
|
if !globalConfig.Callback.CallbackAfterUpdateUserInfoEx.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUpdateUserInfoExReq{
|
cbReq := &cbapi.CallbackAfterUpdateUserInfoExReq{
|
||||||
@ -89,14 +89,14 @@ func CallbackAfterUpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserIn
|
|||||||
Nickname: req.UserInfo.Nickname,
|
Nickname: req.UserInfo.Nickname,
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackAfterUpdateUserInfoExResp{}
|
resp := &cbapi.CallbackAfterUpdateUserInfoExResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfoEx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
func CallbackBeforeUserRegister(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UserRegisterReq) error {
|
||||||
if !config.Config.Callback.CallbackBeforeUserRegister.Enable {
|
if !globalConfig.Callback.CallbackBeforeUserRegister.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
cbReq := &cbapi.CallbackBeforeUserRegisterReq{
|
||||||
@ -106,7 +106,7 @@ func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &cbapi.CallbackBeforeUserRegisterResp{}
|
resp := &cbapi.CallbackBeforeUserRegisterResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackBeforeUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(resp.Users) != 0 {
|
if len(resp.Users) != 0 {
|
||||||
@ -115,8 +115,8 @@ func CallbackBeforeUserRegister(ctx context.Context, req *pbuser.UserRegisterReq
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CallbackAfterUserRegister(ctx context.Context, req *pbuser.UserRegisterReq) error {
|
func CallbackAfterUserRegister(ctx context.Context, globalConfig *config.GlobalConfig, req *pbuser.UserRegisterReq) error {
|
||||||
if !config.Config.Callback.CallbackAfterUserRegister.Enable {
|
if !globalConfig.Callback.CallbackAfterUserRegister.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
cbReq := &cbapi.CallbackAfterUserRegisterReq{
|
||||||
@ -126,7 +126,7 @@ func CallbackAfterUserRegister(ctx context.Context, req *pbuser.UserRegisterReq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
resp := &cbapi.CallbackAfterUserRegisterResp{}
|
resp := &cbapi.CallbackAfterUserRegisterResp{}
|
||||||
if err := http.CallBackPostReturn(ctx, config.Config.Callback.CallbackUrl, cbReq, resp, config.Config.Callback.CallbackAfterUpdateUserInfo); err != nil {
|
if err := http.CallBackPostReturn(ctx, globalConfig.Callback.CallbackUrl, cbReq, resp, globalConfig.Callback.CallbackAfterUpdateUserInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -21,26 +21,34 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/pagination"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/tx"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/protocol/sdkws"
|
"github.com/OpenIMSDK/protocol/sdkws"
|
||||||
pbuser "github.com/OpenIMSDK/protocol/user"
|
|
||||||
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/pagination"
|
|
||||||
"github.com/OpenIMSDK/tools/tx"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||||
|
|
||||||
|
registry "github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/convert"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/controller"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
|
||||||
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
"github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification"
|
||||||
|
|
||||||
|
pbuser "github.com/OpenIMSDK/protocol/user"
|
||||||
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,6 +59,7 @@ type userServer struct {
|
|||||||
friendRpcClient *rpcclient.FriendRpcClient
|
friendRpcClient *rpcclient.FriendRpcClient
|
||||||
groupRpcClient *rpcclient.GroupRpcClient
|
groupRpcClient *rpcclient.GroupRpcClient
|
||||||
RegisterCenter registry.SvcDiscoveryRegistry
|
RegisterCenter registry.SvcDiscoveryRegistry
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGroupOnlineUserReq) (*pbuser.GetGroupOnlineUserResp, error) {
|
func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGroupOnlineUserReq) (*pbuser.GetGroupOnlineUserResp, error) {
|
||||||
@ -58,39 +67,40 @@ func (s *userServer) GetGroupOnlineUser(ctx context.Context, req *pbuser.GetGrou
|
|||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func Start(config *config.GlobalConfig, client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
users := make([]*tablerelation.UserModel, 0)
|
users := make([]*tablerelation.UserModel, 0)
|
||||||
if len(config.Config.IMAdmin.UserID) != len(config.Config.IMAdmin.Nickname) {
|
if len(config.IMAdmin.UserID) != len(config.IMAdmin.Nickname) {
|
||||||
return errors.New("len(config.Config.AppNotificationAdmin.AppManagerUid) != len(config.Config.AppNotificationAdmin.Nickname)")
|
return errors.New("len(s.config.AppNotificationAdmin.AppManagerUid) != len(s.config.AppNotificationAdmin.Nickname)")
|
||||||
}
|
}
|
||||||
for k, v := range config.Config.IMAdmin.UserID {
|
for k, v := range config.IMAdmin.UserID {
|
||||||
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.IMAdmin.Nickname[k], AppMangerLevel: constant.AppNotificationAdmin})
|
users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.IMAdmin.Nickname[k], AppMangerLevel: constant.AppNotificationAdmin})
|
||||||
}
|
}
|
||||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
userDB, err := mgo.NewUserMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt())
|
||||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB)
|
||||||
friendRpcClient := rpcclient.NewFriendRpcClient(client)
|
friendRpcClient := rpcclient.NewFriendRpcClient(client, config)
|
||||||
groupRpcClient := rpcclient.NewGroupRpcClient(client)
|
groupRpcClient := rpcclient.NewGroupRpcClient(client, config)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(client)
|
msgRpcClient := rpcclient.NewMessageRpcClient(client, config)
|
||||||
u := &userServer{
|
u := &userServer{
|
||||||
UserDatabase: database,
|
UserDatabase: database,
|
||||||
RegisterCenter: client,
|
RegisterCenter: client,
|
||||||
friendRpcClient: &friendRpcClient,
|
friendRpcClient: &friendRpcClient,
|
||||||
groupRpcClient: &groupRpcClient,
|
groupRpcClient: &groupRpcClient,
|
||||||
friendNotificationSender: notification.NewFriendNotificationSender(&msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
friendNotificationSender: notification.NewFriendNotificationSender(config, &msgRpcClient, notification.WithDBFunc(database.FindWithError)),
|
||||||
userNotificationSender: notification.NewUserNotificationSender(&msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
userNotificationSender: notification.NewUserNotificationSender(config, &msgRpcClient, notification.WithUserFunc(database.FindWithError)),
|
||||||
|
config: config,
|
||||||
}
|
}
|
||||||
pbuser.RegisterUserServer(server, u)
|
pbuser.RegisterUserServer(server, u)
|
||||||
return u.UserDatabase.InitOnce(context.Background(), users)
|
return u.UserDatabase.InitOnce(context.Background(), users)
|
||||||
@ -111,11 +121,11 @@ func (s *userServer) GetDesignateUsers(ctx context.Context, req *pbuser.GetDesig
|
|||||||
|
|
||||||
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserInfoReq) (resp *pbuser.UpdateUserInfoResp, err error) {
|
||||||
resp = &pbuser.UpdateUserInfoResp{}
|
resp = &pbuser.UpdateUserInfoResp{}
|
||||||
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID)
|
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil {
|
if err := CallbackBeforeUpdateUserInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := convert.UserPb2DBMap(req.UserInfo)
|
data := convert.UserPb2DBMap(req.UserInfo)
|
||||||
@ -128,29 +138,29 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if req.UserInfo.Nickname != "" || req.UserInfo.FaceURL != "" {
|
if req.UserInfo.Nickname != "" || req.UserInfo.FaceURL != "" {
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err = s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err)
|
log.ZError(ctx, "NotificationUserInfoUpdate", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterUpdateUserInfo(ctx, req); err != nil {
|
if err = CallbackAfterUpdateUserInfo(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err = s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
log.ZError(ctx, "NotificationUserInfoUpdate", err, "userID", req.UserInfo.UserID)
|
log.ZError(ctx, "NotificationUserInfoUpdate", err, "userID", req.UserInfo.UserID)
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (resp *pbuser.UpdateUserInfoExResp, err error) {
|
func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUserInfoExReq) (resp *pbuser.UpdateUserInfoExResp, err error) {
|
||||||
resp = &pbuser.UpdateUserInfoExResp{}
|
resp = &pbuser.UpdateUserInfoExResp{}
|
||||||
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID)
|
err = authverify.CheckAccessV3(ctx, req.UserInfo.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CallbackBeforeUpdateUserInfoEx(ctx, req); err != nil {
|
if err = CallbackBeforeUpdateUserInfoEx(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := convert.UserPb2DBMapEx(req.UserInfo)
|
data := convert.UserPb2DBMapEx(req.UserInfo)
|
||||||
@ -170,7 +180,7 @@ func (s *userServer) UpdateUserInfoEx(ctx context.Context, req *pbuser.UpdateUse
|
|||||||
for _, friendID := range friends {
|
for _, friendID := range friends {
|
||||||
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
s.friendNotificationSender.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, friendID)
|
||||||
}
|
}
|
||||||
if err := CallbackAfterUpdateUserInfoEx(ctx, req); err != nil {
|
if err := CallbackAfterUpdateUserInfoEx(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
if err := s.groupRpcClient.NotificationUserInfoUpdate(ctx, req.UserInfo.UserID); err != nil {
|
||||||
@ -197,7 +207,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR
|
|||||||
if utils.Duplicate(req.CheckUserIDs) {
|
if utils.Duplicate(req.CheckUserIDs) {
|
||||||
return nil, errs.ErrArgs.Wrap("userID repeated")
|
return nil, errs.ErrArgs.Wrap("userID repeated")
|
||||||
}
|
}
|
||||||
err = authverify.CheckAdmin(ctx)
|
err = authverify.CheckAdmin(ctx, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -244,8 +254,8 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
if len(req.Users) == 0 {
|
if len(req.Users) == 0 {
|
||||||
return nil, errs.ErrArgs.Wrap("users is empty")
|
return nil, errs.ErrArgs.Wrap("users is empty")
|
||||||
}
|
}
|
||||||
if req.Secret != config.Config.Secret {
|
if req.Secret != s.config.Secret {
|
||||||
log.ZDebug(ctx, "UserRegister", config.Config.Secret, req.Secret)
|
log.ZDebug(ctx, "UserRegister", s.config.Secret, req.Secret)
|
||||||
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
return nil, errs.ErrNoPermission.Wrap("secret invalid")
|
||||||
}
|
}
|
||||||
if utils.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
if utils.DuplicateAny(req.Users, func(e *sdkws.UserInfo) string { return e.UserID }) {
|
||||||
@ -268,7 +278,7 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
if exist {
|
if exist {
|
||||||
return nil, errs.ErrRegisteredAlready.Wrap("userID registered already")
|
return nil, errs.ErrRegisteredAlready.Wrap("userID registered already")
|
||||||
}
|
}
|
||||||
if err := CallbackBeforeUserRegister(ctx, req); err != nil {
|
if err := CallbackBeforeUserRegister(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -288,7 +298,7 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := CallbackAfterUserRegister(ctx, req); err != nil {
|
if err := CallbackAfterUserRegister(ctx, s.config, req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -383,7 +393,7 @@ func (s *userServer) GetSubscribeUsersStatus(ctx context.Context,
|
|||||||
|
|
||||||
// ProcessUserCommandAdd user general function add.
|
// ProcessUserCommandAdd user general function add.
|
||||||
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.ProcessUserCommandAddReq) (*pbuser.ProcessUserCommandAddResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -414,7 +424,7 @@ func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.Proc
|
|||||||
|
|
||||||
// ProcessUserCommandDelete user general function delete.
|
// ProcessUserCommandDelete user general function delete.
|
||||||
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.ProcessUserCommandDeleteReq) (*pbuser.ProcessUserCommandDeleteResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -437,7 +447,7 @@ func (s *userServer) ProcessUserCommandDelete(ctx context.Context, req *pbuser.P
|
|||||||
|
|
||||||
// ProcessUserCommandUpdate user general function update.
|
// ProcessUserCommandUpdate user general function update.
|
||||||
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.ProcessUserCommandUpdateReq) (*pbuser.ProcessUserCommandUpdateResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -469,7 +479,7 @@ func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.P
|
|||||||
|
|
||||||
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.ProcessUserCommandGetReq) (*pbuser.ProcessUserCommandGetResp, error) {
|
||||||
|
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -498,7 +508,7 @@ func (s *userServer) ProcessUserCommandGet(ctx context.Context, req *pbuser.Proc
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
|
func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.ProcessUserCommandGetAllReq) (*pbuser.ProcessUserCommandGetAllResp, error) {
|
||||||
err := authverify.CheckAccessV3(ctx, req.UserID)
|
err := authverify.CheckAccessV3(ctx, req.UserID, s.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -527,7 +537,7 @@ func (s *userServer) ProcessUserCommandGetAll(ctx context.Context, req *pbuser.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.AddNotificationAccountReq) (*pbuser.AddNotificationAccountResp, error) {
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +580,7 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbuser.UpdateNotificationAccountInfoReq) (*pbuser.UpdateNotificationAccountInfoResp, error) {
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,7 +607,7 @@ func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbu
|
|||||||
|
|
||||||
func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) {
|
func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) {
|
||||||
// Check if user is an admin
|
// Check if user is an admin
|
||||||
if err := authverify.CheckIMAdmin(ctx); err != nil {
|
if err := authverify.CheckIMAdmin(ctx, s.config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,7 +681,7 @@ func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pag
|
|||||||
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
||||||
var total int64
|
var total int64
|
||||||
for _, v := range users {
|
for _, v := range users {
|
||||||
if v.AppMangerLevel == constant.AppNotificationAdmin && !utils.IsContain(v.UserID, config.Config.IMAdmin.UserID) {
|
if v.AppMangerLevel == constant.AppNotificationAdmin && !utils.IsContain(v.UserID, s.config.IMAdmin.UserID) {
|
||||||
temp := &pbuser.NotificationAccountInfo{
|
temp := &pbuser.NotificationAccountInfo{
|
||||||
UserID: v.UserID,
|
UserID: v.UserID,
|
||||||
FaceURL: v.FaceURL,
|
FaceURL: v.FaceURL,
|
||||||
|
@ -23,37 +23,38 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StartTask() error {
|
func StartTask(config *config.GlobalConfig) error {
|
||||||
fmt.Println("Cron task start, config:", config.Config.ChatRecordsClearTime)
|
fmt.Println("cron task start, config", config.ChatRecordsClearTime)
|
||||||
|
|
||||||
msgTool, err := InitMsgTool()
|
msgTool, err := InitMsgTool(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
msgTool.convertTools()
|
msgTool.convertTools()
|
||||||
|
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// register cron tasks
|
// register cron tasks
|
||||||
var crontab = cron.New()
|
var crontab = cron.New()
|
||||||
fmt.Printf("Start chatRecordsClearTime cron task, cron config: %s\n", config.Config.ChatRecordsClearTime)
|
fmt.Printf("Start chatRecordsClearTime cron task, cron config: %s\n", config.ChatRecordsClearTime)
|
||||||
_, err = crontab.AddFunc(config.Config.ChatRecordsClearTime, cronWrapFunc(rdb, "cron_clear_msg_and_fix_seq", msgTool.AllConversationClearMsgAndFixSeq))
|
_, err = crontab.AddFunc(config.ChatRecordsClearTime, cronWrapFunc(config,rdb, "cron_clear_msg_and_fix_seq", msgTool.AllConversationClearMsgAndFixSeq))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Start msgDestruct cron task, cron config: %s\n", config.Config.MsgDestructTime)
|
fmt.Printf("Start msgDestruct cron task, cron config: %s\n", config.MsgDestructTime)
|
||||||
_, err = crontab.AddFunc(config.Config.MsgDestructTime, cronWrapFunc(rdb, "cron_conversations_destruct_msgs", msgTool.ConversationsDestructMsgs))
|
_, err = crontab.AddFunc(config.MsgDestructTime, cronWrapFunc(config,rdb, "cron_conversations_destruct_msgs", msgTool.ConversationsDestructMsgs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err, "cron_conversations_destruct_msgs")
|
return errs.Wrap(err, "cron_conversations_destruct_msgs")
|
||||||
}
|
}
|
||||||
@ -91,8 +92,8 @@ func netlock(rdb redis.UniversalClient, key string, ttl time.Duration) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
func cronWrapFunc(rdb redis.UniversalClient, key string, fn func()) func() {
|
func cronWrapFunc(config *config.GlobalConfig, rdb redis.UniversalClient, key string, fn func()) func() {
|
||||||
enableCronLocker := config.Config.EnableCronLocker
|
enableCronLocker := config.EnableCronLocker
|
||||||
return func() {
|
return func() {
|
||||||
// if don't enable cron-locker, call fn directly.
|
// if don't enable cron-locker, call fn directly.
|
||||||
if !enableCronLocker {
|
if !enableCronLocker {
|
||||||
|
@ -15,8 +15,12 @@
|
|||||||
package tools
|
package tools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -61,7 +65,7 @@ func TestCronWrapFunc(t *testing.T) {
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
key := fmt.Sprintf("cron-%v", rand.Int31())
|
key := fmt.Sprintf("cron-%v", rand.Int31())
|
||||||
crontab := cron.New(cron.WithSeconds())
|
crontab := cron.New(cron.WithSeconds())
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, cb))
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(config.NewGlobalConfig(), rdb, key, cb))
|
||||||
crontab.Start()
|
crontab.Start()
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
@ -71,7 +75,11 @@ func TestCronWrapFunc(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCronWrapFuncWithNetlock(t *testing.T) {
|
func TestCronWrapFuncWithNetlock(t *testing.T) {
|
||||||
config.Config.EnableCronLocker = true
|
conf, err := initCfg()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
conf.EnableCronLocker = true
|
||||||
rdb := redis.NewClient(&redis.Options{})
|
rdb := redis.NewClient(&redis.Options{})
|
||||||
defer rdb.Close()
|
defer rdb.Close()
|
||||||
|
|
||||||
@ -80,10 +88,10 @@ func TestCronWrapFuncWithNetlock(t *testing.T) {
|
|||||||
crontab := cron.New(cron.WithSeconds())
|
crontab := cron.New(cron.WithSeconds())
|
||||||
|
|
||||||
key := fmt.Sprintf("cron-%v", rand.Int31())
|
key := fmt.Sprintf("cron-%v", rand.Int31())
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, func() {
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
|
||||||
done <- "host1"
|
done <- "host1"
|
||||||
}))
|
}))
|
||||||
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(rdb, key, func() {
|
crontab.AddFunc("*/1 * * * * *", cronWrapFunc(conf, rdb, key, func() {
|
||||||
done <- "host2"
|
done <- "host2"
|
||||||
}))
|
}))
|
||||||
crontab.Start()
|
crontab.Start()
|
||||||
@ -94,3 +102,22 @@ func TestCronWrapFuncWithNetlock(t *testing.T) {
|
|||||||
|
|
||||||
crontab.Stop()
|
crontab.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initCfg() (*config.GlobalConfig, error) {
|
||||||
|
const (
|
||||||
|
defaultCfgPath = "../../../../../config/config.yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
cfgPath := flag.String("c", defaultCfgPath, "Path to the configuration file")
|
||||||
|
data, err := os.ReadFile(*cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err, "ReadFile unmarshal failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
conf := config.NewGlobalConfig()
|
||||||
|
err = yaml.Unmarshal(data, &conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errs.Wrap(err, "InitConfig unmarshal failed")
|
||||||
|
}
|
||||||
|
return conf, nil
|
||||||
|
}
|
||||||
|
@ -46,10 +46,12 @@ type MsgTool struct {
|
|||||||
userDatabase controller.UserDatabase
|
userDatabase controller.UserDatabase
|
||||||
groupDatabase controller.GroupDatabase
|
groupDatabase controller.GroupDatabase
|
||||||
msgNotificationSender *notification.MsgNotificationSender
|
msgNotificationSender *notification.MsgNotificationSender
|
||||||
|
Config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
|
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
|
||||||
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender,
|
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase,
|
||||||
|
msgNotificationSender *notification.MsgNotificationSender, config *config.GlobalConfig,
|
||||||
) *MsgTool {
|
) *MsgTool {
|
||||||
return &MsgTool{
|
return &MsgTool{
|
||||||
msgDatabase: msgDatabase,
|
msgDatabase: msgDatabase,
|
||||||
@ -57,32 +59,33 @@ func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controlle
|
|||||||
groupDatabase: groupDatabase,
|
groupDatabase: groupDatabase,
|
||||||
conversationDatabase: conversationDatabase,
|
conversationDatabase: conversationDatabase,
|
||||||
msgNotificationSender: msgNotificationSender,
|
msgNotificationSender: msgNotificationSender,
|
||||||
|
Config: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitMsgTool() (*MsgTool, error) {
|
func InitMsgTool(config *config.GlobalConfig) (*MsgTool, error) {
|
||||||
rdb, err := cache.NewRedis()
|
rdb, err := cache.NewRedis(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
discov, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
discov, err := kdisc.NewDiscoveryRegister(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
userDB, err := mgo.NewUserMongo(mongo.GetDatabase())
|
userDB, err := mgo.NewUserMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msgDatabase, err := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
|
msgDatabase, err := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase(config.Mongo.Database), config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase())
|
userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase(config.Mongo.Database))
|
||||||
ctxTx := tx.NewMongo(mongo.GetClient())
|
ctxTx := tx.NewMongo(mongo.GetClient())
|
||||||
userDatabase := controller.NewUserDatabase(
|
userDatabase := controller.NewUserDatabase(
|
||||||
userDB,
|
userDB,
|
||||||
@ -90,19 +93,19 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
ctxTx,
|
ctxTx,
|
||||||
userMongoDB,
|
userMongoDB,
|
||||||
)
|
)
|
||||||
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase())
|
groupDB, err := mgo.NewGroupMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase())
|
groupMemberDB, err := mgo.NewGroupMember(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase())
|
groupRequestDB, err := mgo.NewGroupRequestMgo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase())
|
conversationDB, err := mgo.NewConversationMongo(mongo.GetDatabase(config.Mongo.Database))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -112,9 +115,9 @@ func InitMsgTool() (*MsgTool, error) {
|
|||||||
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), conversationDB),
|
||||||
ctxTx,
|
ctxTx,
|
||||||
)
|
)
|
||||||
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
|
msgRpcClient := rpcclient.NewMessageRpcClient(discov, config)
|
||||||
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
|
msgNotificationSender := notification.NewMsgNotificationSender(config, rpcclient.WithRpcClient(&msgRpcClient))
|
||||||
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender)
|
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender, config)
|
||||||
return msgTool, nil
|
return msgTool, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,8 +179,8 @@ func (c *MsgTool) AllConversationClearMsgAndFixSeq() {
|
|||||||
|
|
||||||
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
|
func (c *MsgTool) ClearConversationsMsg(ctx context.Context, conversationIDs []string) {
|
||||||
for _, conversationID := range conversationIDs {
|
for _, conversationID := range conversationIDs {
|
||||||
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(config.Config.RetainChatRecords*24*60*60)); err != nil {
|
if err := c.msgDatabase.DeleteConversationMsgsAndSetMinSeq(ctx, conversationID, int64(c.Config.RetainChatRecords*24*60*60)); err != nil {
|
||||||
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", config.Config.RetainChatRecords)
|
log.ZError(ctx, "DeleteUserSuperGroupMsgsAndSetMinSeq failed", err, "conversationID", conversationID, "DBRetainChatRecords", c.Config.RetainChatRecords)
|
||||||
}
|
}
|
||||||
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
|
if err := c.checkMaxSeq(ctx, conversationID); err != nil {
|
||||||
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
|
log.ZError(ctx, "fixSeq failed", err, "conversationID", conversationID)
|
||||||
|
@ -26,61 +26,60 @@ import (
|
|||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Secret() jwt.Keyfunc {
|
func Secret(secret string) jwt.Keyfunc {
|
||||||
return func(token *jwt.Token) (any, error) {
|
return func(token *jwt.Token) (any, error) {
|
||||||
return []byte(config.Config.Secret), nil
|
return []byte(secret), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) {
|
func CheckAccessV3(ctx context.Context, ownerUserID string, config *config.GlobalConfig) (err error) {
|
||||||
opUserID := mcontext.GetOpUserID(ctx)
|
opUserID := mcontext.GetOpUserID(ctx)
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(opUserID, config.Config.IMAdmin.UserID) {
|
if utils.IsContain(opUserID, config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if opUserID == ownerUserID {
|
if opUserID == ownerUserID {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.Wrap(errs.ErrNoPermission, "CheckAccessV3: no permission for user "+opUserID)
|
return errs.ErrNoPermission.Wrap("ownerUserID", ownerUserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsAppManagerUid(ctx context.Context) bool {
|
func IsAppManagerUid(ctx context.Context, config *config.GlobalConfig) bool {
|
||||||
return (len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID)) ||
|
return (len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID)) ||
|
||||||
utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID)
|
utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAdmin(ctx context.Context) error {
|
func CheckAdmin(ctx context.Context, config *config.GlobalConfig) error {
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID) {
|
if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not admin userID", mcontext.GetOpUserID(ctx)))
|
||||||
}
|
}
|
||||||
|
func CheckIMAdmin(ctx context.Context, config *config.GlobalConfig) error {
|
||||||
func CheckIMAdmin(ctx context.Context) error {
|
if utils.IsContain(mcontext.GetOpUserID(ctx), config.IMAdmin.UserID) {
|
||||||
if utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.IMAdmin.UserID) {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(config.Config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Config.Manager.UserID) {
|
if len(config.Manager.UserID) > 0 && utils.IsContain(mcontext.GetOpUserID(ctx), config.Manager.UserID) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not CheckIMAdmin userID", mcontext.GetOpUserID(ctx)))
|
return errs.ErrNoPermission.Wrap(fmt.Sprintf("user %s is not CheckIMAdmin userID", mcontext.GetOpUserID(ctx)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseRedisInterfaceToken(redisToken any) (*tokenverify.Claims, error) {
|
func ParseRedisInterfaceToken(redisToken any, secret string) (*tokenverify.Claims, error) {
|
||||||
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret())
|
return tokenverify.GetClaimFromToken(string(redisToken.([]uint8)), Secret(secret))
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsManagerUserID(opUserID string) bool {
|
func IsManagerUserID(opUserID string, config *config.GlobalConfig) bool {
|
||||||
return (len(config.Config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Config.Manager.UserID)) || utils.IsContain(opUserID, config.Config.IMAdmin.UserID)
|
return (len(config.Manager.UserID) > 0 && utils.IsContain(opUserID, config.Manager.UserID)) || utils.IsContain(opUserID, config.IMAdmin.UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func WsVerifyToken(token, userID string, platformID int) error {
|
func WsVerifyToken(token, userID, secret string, platformID int) error {
|
||||||
claim, err := tokenverify.GetClaimFromToken(token, Secret())
|
claim, err := tokenverify.GetClaimFromToken(token, Secret(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -15,54 +15,44 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
"github.com/openimsdk/open-im-server/v3/internal/api"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ApiCmd struct {
|
type ApiCmd struct {
|
||||||
*RootCmd
|
*RootCmd
|
||||||
|
initFunc func(config *config.GlobalConfig, port int, promPort int) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApiCmd() *ApiCmd {
|
func NewApiCmd() *ApiCmd {
|
||||||
ret := &ApiCmd{NewRootCmd("api")}
|
ret := &ApiCmd{RootCmd: NewRootCmd("api"), initFunc: api.Start}
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
|
ret.addPreRun()
|
||||||
|
ret.addRunE()
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddApi configures the API command to run with specified ports for the API and Prometheus monitoring.
|
func (a *ApiCmd) addPreRun() {
|
||||||
// It ensures error handling for port retrieval and only proceeds if both port numbers are successfully obtained.
|
a.Command.PreRun = func(cmd *cobra.Command, args []string) {
|
||||||
func (a *ApiCmd) AddApi(f func(port int, promPort int) error) {
|
a.port = a.getPortFlag(cmd)
|
||||||
|
a.prometheusPort = a.getPrometheusPortFlag(cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *ApiCmd) addRunE() {
|
||||||
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
port, err := a.getPortFlag(cmd)
|
return a.initFunc(a.config, a.port, a.prometheusPort)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
promPort, err := a.getPrometheusPortFlag(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return f(port, promPort)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ApiCmd) GetPortFromConfig(portType string) (int, error) {
|
func (a *ApiCmd) GetPortFromConfig(portType string) int {
|
||||||
if portType == constant.FlagPort {
|
if portType == constant.FlagPort {
|
||||||
if len(config2.Config.Api.OpenImApiPort) > 0 {
|
return a.config.Api.OpenImApiPort[0]
|
||||||
return config2.Config.Api.OpenImApiPort[0], nil
|
|
||||||
}
|
|
||||||
return 0, errors.New("API port configuration is empty or missing")
|
|
||||||
} else if portType == constant.FlagPrometheusPort {
|
} else if portType == constant.FlagPrometheusPort {
|
||||||
if len(config2.Config.Prometheus.ApiPrometheusPort) > 0 {
|
return a.config.Prometheus.ApiPrometheusPort[0]
|
||||||
return config2.Config.Prometheus.ApiPrometheusPort[0], nil
|
|
||||||
}
|
|
||||||
return 0, errors.New("Prometheus port configuration is empty or missing")
|
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unknown port type: %s", portType)
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -14,29 +14,35 @@
|
|||||||
|
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import "github.com/spf13/cobra"
|
import (
|
||||||
|
"github.com/openimsdk/open-im-server/v3/internal/tools"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
type CronTaskCmd struct {
|
type CronTaskCmd struct {
|
||||||
*RootCmd
|
*RootCmd
|
||||||
|
initFunc func(config *config.GlobalConfig) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCronTaskCmd() *CronTaskCmd {
|
func NewCronTaskCmd() *CronTaskCmd {
|
||||||
ret := &CronTaskCmd{NewRootCmd("cronTask", WithCronTaskLogName())}
|
ret := &CronTaskCmd{RootCmd: NewRootCmd("cronTask", WithCronTaskLogName()),
|
||||||
|
initFunc: tools.StartTask}
|
||||||
|
ret.addRunE()
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CronTaskCmd) addRunE(f func() error) {
|
func (c *CronTaskCmd) addRunE() {
|
||||||
c.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
c.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
return f()
|
return c.initFunc(c.config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CronTaskCmd) Exec(f func() error) error {
|
func (c *CronTaskCmd) Exec() error {
|
||||||
c.addRunE(f)
|
|
||||||
return c.Execute()
|
return c.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CronTaskCmd) GetPortFromConfig(portType string) (int, error) {
|
func (c *CronTaskCmd) GetPortFromConfig(portType string) int {
|
||||||
return 0, nil
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"log"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
|
"github.com/openimsdk/open-im-server/v3/internal/msggateway"
|
||||||
v3config "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgGatewayCmd struct {
|
type MsgGatewayCmd struct {
|
||||||
@ -30,6 +30,7 @@ type MsgGatewayCmd struct {
|
|||||||
|
|
||||||
func NewMsgGatewayCmd() *MsgGatewayCmd {
|
func NewMsgGatewayCmd() *MsgGatewayCmd {
|
||||||
ret := &MsgGatewayCmd{NewRootCmd("msgGateway")}
|
ret := &MsgGatewayCmd{NewRootCmd("msgGateway")}
|
||||||
|
ret.addRunE()
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -38,67 +39,39 @@ func (m *MsgGatewayCmd) AddWsPortFlag() {
|
|||||||
m.Command.Flags().IntP(constant.FlagWsPort, "w", 0, "ws server listen port")
|
m.Command.Flags().IntP(constant.FlagWsPort, "w", 0, "ws server listen port")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) (int, error) {
|
func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) int {
|
||||||
port, err := cmd.Flags().GetInt(constant.FlagWsPort)
|
port, err := cmd.Flags().GetInt(constant.FlagWsPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, errs.Wrap(err, "error getting ws port flag")
|
log.Println("Error getting ws port flag:", err)
|
||||||
}
|
}
|
||||||
if port == 0 {
|
if port == 0 {
|
||||||
port, _ = m.PortFromConfig(constant.FlagWsPort)
|
port = m.PortFromConfig(constant.FlagWsPort)
|
||||||
}
|
}
|
||||||
return port, nil
|
return port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgGatewayCmd) addRunE() {
|
func (m *MsgGatewayCmd) addRunE() {
|
||||||
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
wsPort, err := m.getWsPortFlag(cmd)
|
return msggateway.RunWsAndServer(m.config, m.getPortFlag(cmd), m.getWsPortFlag(cmd), m.getPrometheusPortFlag(cmd))
|
||||||
if err != nil {
|
|
||||||
return errs.Wrap(err, "failed to get WS port flag")
|
|
||||||
}
|
|
||||||
port, err := m.getPortFlag(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
prometheusPort, err := m.getPrometheusPortFlag(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return msggateway.RunWsAndServer(port, wsPort, prometheusPort)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgGatewayCmd) Exec() error {
|
func (m *MsgGatewayCmd) Exec() error {
|
||||||
m.addRunE()
|
|
||||||
return m.Execute()
|
return m.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgGatewayCmd) GetPortFromConfig(portType string) (int, error) {
|
func (m *MsgGatewayCmd) GetPortFromConfig(portType string) int {
|
||||||
var port int
|
|
||||||
var exists bool
|
|
||||||
|
|
||||||
switch portType {
|
switch portType {
|
||||||
case constant.FlagWsPort:
|
case constant.FlagWsPort:
|
||||||
if len(v3config.Config.LongConnSvr.OpenImWsPort) > 0 {
|
return m.config.LongConnSvr.OpenImWsPort[0]
|
||||||
port = v3config.Config.LongConnSvr.OpenImWsPort[0]
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
|
|
||||||
case constant.FlagPort:
|
case constant.FlagPort:
|
||||||
if len(v3config.Config.LongConnSvr.OpenImMessageGatewayPort) > 0 {
|
return m.config.LongConnSvr.OpenImMessageGatewayPort[0]
|
||||||
port = v3config.Config.LongConnSvr.OpenImMessageGatewayPort[0]
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
|
|
||||||
case constant.FlagPrometheusPort:
|
case constant.FlagPrometheusPort:
|
||||||
if len(v3config.Config.Prometheus.MessageGatewayPrometheusPort) > 0 {
|
return m.config.Prometheus.MessageGatewayPrometheusPort[0]
|
||||||
port = v3config.Config.Prometheus.MessageGatewayPrometheusPort[0]
|
|
||||||
exists = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !exists {
|
default:
|
||||||
return 0, errs.Wrap(errors.New("port type '%s' not found in configuration"), portType)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return port, nil
|
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ func TestMsgGatewayCmd_GetPortFromConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.portType, func(t *testing.T) {
|
t.Run(tt.portType, func(t *testing.T) {
|
||||||
got, _ := msgGatewayCmd.GetPortFromConfig(tt.portType)
|
got := msgGatewayCmd.GetPortFromConfig(tt.portType)
|
||||||
assert.Equal(t, tt.want, got)
|
assert.Equal(t, tt.want, got)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,10 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/openimsdk/open-im-server/v3/internal/msgtransfer"
|
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/internal/msgtransfer"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MsgTransferCmd struct {
|
type MsgTransferCmd struct {
|
||||||
@ -29,37 +28,29 @@ type MsgTransferCmd struct {
|
|||||||
|
|
||||||
func NewMsgTransferCmd() *MsgTransferCmd {
|
func NewMsgTransferCmd() *MsgTransferCmd {
|
||||||
ret := &MsgTransferCmd{NewRootCmd("msgTransfer")}
|
ret := &MsgTransferCmd{NewRootCmd("msgTransfer")}
|
||||||
|
ret.addRunE()
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransferCmd) addRunE() {
|
func (m *MsgTransferCmd) addRunE() {
|
||||||
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
m.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
prometheusPort, err := m.getPrometheusPortFlag(cmd)
|
return msgtransfer.StartTransfer(m.config, m.getPrometheusPortFlag(cmd))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return msgtransfer.StartTransfer(prometheusPort)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransferCmd) Exec() error {
|
func (m *MsgTransferCmd) Exec() error {
|
||||||
m.addRunE()
|
|
||||||
return m.Execute()
|
return m.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransferCmd) GetPortFromConfig(portType string) (int, error) {
|
func (m *MsgTransferCmd) GetPortFromConfig(portType string) int {
|
||||||
if portType == constant.FlagPort {
|
if portType == constant.FlagPort {
|
||||||
return 0, nil
|
return 0
|
||||||
} else if portType == constant.FlagPrometheusPort {
|
} else if portType == constant.FlagPrometheusPort {
|
||||||
n := m.getTransferProgressFlagValue()
|
n := m.getTransferProgressFlagValue()
|
||||||
|
return m.config.Prometheus.MessageTransferPrometheusPort[n]
|
||||||
if n < len(config2.Config.Prometheus.MessageTransferPrometheusPort) {
|
|
||||||
return config2.Config.Prometheus.MessageTransferPrometheusPort[n], nil
|
|
||||||
}
|
|
||||||
return 0, fmt.Errorf("index out of range for MessageTransferPrometheusPort with index %d", n)
|
|
||||||
}
|
}
|
||||||
return 0, fmt.Errorf("unknown port type: %s", portType)
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransferCmd) AddTransferProgressFlag() {
|
func (m *MsgTransferCmd) AddTransferProgressFlag() {
|
||||||
@ -67,10 +58,10 @@ func (m *MsgTransferCmd) AddTransferProgressFlag() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgTransferCmd) getTransferProgressFlagValue() int {
|
func (m *MsgTransferCmd) getTransferProgressFlagValue() int {
|
||||||
nindex, err := m.Command.Flags().GetInt(constant.FlagTransferProgressIndex)
|
nIndex, err := m.Command.Flags().GetInt(constant.FlagTransferProgressIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("get transfercmd error,make sure it is k8s env or not")
|
fmt.Println("get transfer cmd error,make sure it is k8s env or not")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return nindex
|
return nIndex
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
type MsgUtilsCmd struct {
|
type MsgUtilsCmd struct {
|
||||||
cobra.Command
|
cobra.Command
|
||||||
|
MsgTool *tools.MsgTool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MsgUtilsCmd) AddUserIDFlag() {
|
func (m *MsgUtilsCmd) AddUserIDFlag() {
|
||||||
@ -135,7 +136,7 @@ func NewSeqCmd() *SeqCmd {
|
|||||||
|
|
||||||
func (s *SeqCmd) GetSeqCmd() *cobra.Command {
|
func (s *SeqCmd) GetSeqCmd() *cobra.Command {
|
||||||
s.Command.Run = func(cmdLines *cobra.Command, args []string) {
|
s.Command.Run = func(cmdLines *cobra.Command, args []string) {
|
||||||
_, err := tools.InitMsgTool()
|
_, err := tools.InitMsgTool(s.MsgTool.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type RootCmdPt interface {
|
type RootCmdPt interface {
|
||||||
GetPortFromConfig(portType string) (int, error)
|
GetPortFromConfig(portType string) int
|
||||||
}
|
}
|
||||||
|
|
||||||
type RootCmd struct {
|
type RootCmd struct {
|
||||||
@ -35,6 +35,11 @@ type RootCmd struct {
|
|||||||
port int
|
port int
|
||||||
prometheusPort int
|
prometheusPort int
|
||||||
cmdItf RootCmdPt
|
cmdItf RootCmdPt
|
||||||
|
config *config.GlobalConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *RootCmd) Port() int {
|
||||||
|
return rc.port
|
||||||
}
|
}
|
||||||
|
|
||||||
type CmdOpts struct {
|
type CmdOpts struct {
|
||||||
@ -54,7 +59,7 @@ func WithLogName(logName string) func(*CmdOpts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewRootCmd(name string, opts ...func(*CmdOpts)) *RootCmd {
|
func NewRootCmd(name string, opts ...func(*CmdOpts)) *RootCmd {
|
||||||
rootCmd := &RootCmd{Name: name}
|
rootCmd := &RootCmd{Name: name, config: config.NewGlobalConfig()}
|
||||||
cmd := cobra.Command{
|
cmd := cobra.Command{
|
||||||
Use: "Start openIM application",
|
Use: "Start openIM application",
|
||||||
Short: fmt.Sprintf(`Start %s `, name),
|
Short: fmt.Sprintf(`Start %s `, name),
|
||||||
@ -96,7 +101,7 @@ func (rc *RootCmd) applyOptions(opts ...func(*CmdOpts)) *CmdOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rc *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
|
func (rc *RootCmd) initializeLogger(cmdOpts *CmdOpts) error {
|
||||||
logConfig := config.Config.Log
|
logConfig := rc.config.Log
|
||||||
|
|
||||||
return log.InitFromConfig(
|
return log.InitFromConfig(
|
||||||
|
|
||||||
@ -129,41 +134,36 @@ func (r *RootCmd) AddPortFlag() {
|
|||||||
r.Command.Flags().IntP(constant.FlagPort, "p", 0, "server listen port")
|
r.Command.Flags().IntP(constant.FlagPort, "p", 0, "server listen port")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) getPortFlag(cmd *cobra.Command) (int, error) {
|
func (r *RootCmd) getPortFlag(cmd *cobra.Command) int {
|
||||||
port, err := cmd.Flags().GetInt(constant.FlagPort)
|
port, err := cmd.Flags().GetInt(constant.FlagPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Wrapping the error with additional context
|
// Wrapping the error with additional context
|
||||||
return 0, errs.Wrap(err, "error getting port flag")
|
return 0
|
||||||
}
|
}
|
||||||
if port == 0 {
|
if port == 0 {
|
||||||
port, _ = r.PortFromConfig(constant.FlagPort)
|
port = r.PortFromConfig(constant.FlagPort)
|
||||||
// port, err := r.PortFromConfig(constant.FlagPort)
|
|
||||||
// if err != nil {
|
|
||||||
// // Optionally wrap the error if it's an internal error needing context
|
|
||||||
// return 0, errs.Wrap(err, "error getting port from config")
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return port, nil
|
return port
|
||||||
}
|
}
|
||||||
|
|
||||||
// // GetPortFlag returns the port flag.
|
// // GetPortFlag returns the port flag.
|
||||||
func (r *RootCmd) GetPortFlag() (int, error) {
|
func (r *RootCmd) GetPortFlag() int {
|
||||||
return r.port, nil
|
return r.port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) AddPrometheusPortFlag() {
|
func (r *RootCmd) AddPrometheusPortFlag() {
|
||||||
r.Command.Flags().IntP(constant.FlagPrometheusPort, "", 0, "server prometheus listen port")
|
r.Command.Flags().IntP(constant.FlagPrometheusPort, "", 0, "server prometheus listen port")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) (int, error) {
|
func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
|
||||||
port, err := cmd.Flags().GetInt(constant.FlagPrometheusPort)
|
port, err := cmd.Flags().GetInt(constant.FlagPrometheusPort)
|
||||||
if err != nil || port == 0 {
|
if err != nil || port == 0 {
|
||||||
port, err = r.PortFromConfig(constant.FlagPrometheusPort)
|
port = r.PortFromConfig(constant.FlagPrometheusPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return port, nil
|
return port
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) GetPrometheusPortFlag() int {
|
func (r *RootCmd) GetPrometheusPortFlag() int {
|
||||||
@ -173,7 +173,7 @@ func (r *RootCmd) GetPrometheusPortFlag() int {
|
|||||||
func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error {
|
func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error {
|
||||||
configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf)
|
configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf)
|
||||||
fmt.Println("The directory of the configuration file to start the process:", configFolderPath)
|
fmt.Println("The directory of the configuration file to start the process:", configFolderPath)
|
||||||
return config2.InitConfig(configFolderPath)
|
return config2.InitConfig(r.config, configFolderPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) Execute() error {
|
func (r *RootCmd) Execute() error {
|
||||||
@ -184,11 +184,8 @@ func (r *RootCmd) AddCommand(cmds ...*cobra.Command) {
|
|||||||
r.Command.AddCommand(cmds...)
|
r.Command.AddCommand(cmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) PortFromConfig(portType string) (int, error) {
|
func (r *RootCmd) PortFromConfig(portType string) int {
|
||||||
// Retrieve the port and cache it
|
// Retrieve the port and cache it
|
||||||
port, err := r.cmdItf.GetPortFromConfig(portType)
|
port := r.cmdItf.GetPortFromConfig(portType)
|
||||||
if err != nil {
|
return port
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return port, nil
|
|
||||||
}
|
}
|
||||||
|
@ -16,100 +16,144 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/startrpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type rpcInitFuc func(config *config2.GlobalConfig, disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error
|
||||||
|
|
||||||
type RpcCmd struct {
|
type RpcCmd struct {
|
||||||
*RootCmd
|
*RootCmd
|
||||||
|
RpcRegisterName string
|
||||||
|
initFunc rpcInitFuc
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRpcCmd(name string) *RpcCmd {
|
func NewRpcCmd(name string, initFunc rpcInitFuc) *RpcCmd {
|
||||||
ret := &RpcCmd{NewRootCmd(name)}
|
ret := &RpcCmd{RootCmd: NewRootCmd(name), initFunc: initFunc}
|
||||||
|
ret.addPreRun()
|
||||||
|
ret.addRunE()
|
||||||
ret.SetRootCmdPt(ret)
|
ret.SetRootCmdPt(ret)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *RpcCmd) Exec() error {
|
func (a *RpcCmd) addPreRun() {
|
||||||
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
a.Command.PreRun = func(cmd *cobra.Command, args []string) {
|
||||||
portFlag, err := a.getPortFlag(cmd)
|
a.port = a.getPortFlag(cmd)
|
||||||
if err != nil {
|
a.prometheusPort = a.getPrometheusPortFlag(cmd)
|
||||||
return err
|
|
||||||
}
|
|
||||||
a.port = portFlag
|
|
||||||
|
|
||||||
prometheusPort, err := a.getPrometheusPortFlag(cmd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
a.prometheusPort = prometheusPort
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RpcCmd) addRunE() {
|
||||||
|
a.Command.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
|
rpcRegisterName, err := a.GetRpcRegisterNameFromConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return a.StartSvr(rpcRegisterName, a.initFunc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *RpcCmd) Exec() error {
|
||||||
return a.Execute()
|
return a.Execute()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *RpcCmd) StartSvr(name string, rpcFn func(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
func (a *RpcCmd) StartSvr(name string, rpcFn func(config *config2.GlobalConfig, disCov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
|
||||||
portFlag, err := a.GetPortFlag()
|
if a.GetPortFlag() == 0 {
|
||||||
if err != nil {
|
return errs.Wrap(errors.New("port is required"))
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
a.port = portFlag
|
|
||||||
}
|
}
|
||||||
|
return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), a.config, rpcFn)
|
||||||
return startrpc.Start(portFlag, name, a.GetPrometheusPortFlag(), rpcFn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *RpcCmd) GetPortFromConfig(portType string) (int, error) {
|
func (a *RpcCmd) GetPortFromConfig(portType string) int {
|
||||||
portConfigMap := map[string]map[string]int{
|
switch a.Name {
|
||||||
RpcPushServer: {
|
case RpcPushServer:
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImPushPort[0],
|
if portType == constant.FlagPort {
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.PushPrometheusPort[0],
|
return a.config.RpcPort.OpenImPushPort[0]
|
||||||
},
|
}
|
||||||
RpcAuthServer: {
|
if portType == constant.FlagPrometheusPort {
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImAuthPort[0],
|
return a.config.Prometheus.PushPrometheusPort[0]
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.AuthPrometheusPort[0],
|
}
|
||||||
},
|
case RpcAuthServer:
|
||||||
RpcConversationServer: {
|
if portType == constant.FlagPort {
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImConversationPort[0],
|
return a.config.RpcPort.OpenImAuthPort[0]
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.ConversationPrometheusPort[0],
|
}
|
||||||
},
|
if portType == constant.FlagPrometheusPort {
|
||||||
RpcFriendServer: {
|
return a.config.Prometheus.AuthPrometheusPort[0]
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImFriendPort[0],
|
}
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.FriendPrometheusPort[0],
|
case RpcConversationServer:
|
||||||
},
|
if portType == constant.FlagPort {
|
||||||
RpcGroupServer: {
|
return a.config.RpcPort.OpenImConversationPort[0]
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImGroupPort[0],
|
}
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.GroupPrometheusPort[0],
|
if portType == constant.FlagPrometheusPort {
|
||||||
},
|
return a.config.Prometheus.ConversationPrometheusPort[0]
|
||||||
RpcMsgServer: {
|
}
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImMessagePort[0],
|
case RpcFriendServer:
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.MessagePrometheusPort[0],
|
if portType == constant.FlagPort {
|
||||||
},
|
return a.config.RpcPort.OpenImFriendPort[0]
|
||||||
RpcThirdServer: {
|
}
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImThirdPort[0],
|
if portType == constant.FlagPrometheusPort {
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.ThirdPrometheusPort[0],
|
return a.config.Prometheus.FriendPrometheusPort[0]
|
||||||
},
|
}
|
||||||
RpcUserServer: {
|
case RpcGroupServer:
|
||||||
constant.FlagPort: config2.Config.RpcPort.OpenImUserPort[0],
|
if portType == constant.FlagPort {
|
||||||
constant.FlagPrometheusPort: config2.Config.Prometheus.UserPrometheusPort[0],
|
return a.config.RpcPort.OpenImGroupPort[0]
|
||||||
},
|
}
|
||||||
}
|
if portType == constant.FlagPrometheusPort {
|
||||||
|
return a.config.Prometheus.GroupPrometheusPort[0]
|
||||||
if portMap, ok := portConfigMap[a.Name]; ok {
|
}
|
||||||
if port, ok := portMap[portType]; ok {
|
case RpcMsgServer:
|
||||||
return port, nil
|
if portType == constant.FlagPort {
|
||||||
} else {
|
return a.config.RpcPort.OpenImMessagePort[0]
|
||||||
return 0, errs.Wrap(errors.New("port type not found"), fmt.Sprintf("Failed to get port for %s", a.Name))
|
}
|
||||||
|
if portType == constant.FlagPrometheusPort {
|
||||||
|
return a.config.Prometheus.MessagePrometheusPort[0]
|
||||||
|
}
|
||||||
|
case RpcThirdServer:
|
||||||
|
if portType == constant.FlagPort {
|
||||||
|
return a.config.RpcPort.OpenImThirdPort[0]
|
||||||
|
}
|
||||||
|
if portType == constant.FlagPrometheusPort {
|
||||||
|
return a.config.Prometheus.ThirdPrometheusPort[0]
|
||||||
|
}
|
||||||
|
case RpcUserServer:
|
||||||
|
if portType == constant.FlagPort {
|
||||||
|
return a.config.RpcPort.OpenImUserPort[0]
|
||||||
|
}
|
||||||
|
if portType == constant.FlagPrometheusPort {
|
||||||
|
return a.config.Prometheus.UserPrometheusPort[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0
|
||||||
return 0, errs.Wrap(fmt.Errorf("server name '%s' not found", a.Name), "Failed to get port configuration")
|
}
|
||||||
|
|
||||||
|
func (a *RpcCmd) GetRpcRegisterNameFromConfig() (string, error) {
|
||||||
|
switch a.Name {
|
||||||
|
case RpcPushServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImPushName, nil
|
||||||
|
case RpcAuthServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImAuthName, nil
|
||||||
|
case RpcConversationServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImConversationName, nil
|
||||||
|
case RpcFriendServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImFriendName, nil
|
||||||
|
case RpcGroupServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImGroupName, nil
|
||||||
|
case RpcMsgServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImMsgName, nil
|
||||||
|
case RpcThirdServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImThirdName, nil
|
||||||
|
case RpcUserServer:
|
||||||
|
return a.config.RpcRegisterName.OpenImUserName, nil
|
||||||
|
}
|
||||||
|
return "", errs.Wrap(errors.New("can not get rpc register name"), a.Name)
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Config configStruct
|
var Config GlobalConfig
|
||||||
|
|
||||||
const ConfKey = "conf"
|
const ConfKey = "conf"
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ type MYSQL struct {
|
|||||||
SlowThreshold int `yaml:"slowThreshold"`
|
SlowThreshold int `yaml:"slowThreshold"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type configStruct struct {
|
type GlobalConfig struct {
|
||||||
Envs struct {
|
Envs struct {
|
||||||
Discovery string `yaml:"discovery"`
|
Discovery string `yaml:"discovery"`
|
||||||
}
|
}
|
||||||
@ -339,6 +339,10 @@ type configStruct struct {
|
|||||||
Notification notification `yaml:"notification"`
|
Notification notification `yaml:"notification"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewGlobalConfig() *GlobalConfig {
|
||||||
|
return &GlobalConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
type notification struct {
|
type notification struct {
|
||||||
GroupCreated NotificationConf `yaml:"groupCreated"`
|
GroupCreated NotificationConf `yaml:"groupCreated"`
|
||||||
GroupInfoSet NotificationConf `yaml:"groupInfoSet"`
|
GroupInfoSet NotificationConf `yaml:"groupInfoSet"`
|
||||||
@ -378,7 +382,7 @@ type notification struct {
|
|||||||
ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"`
|
ConversationSetPrivate NotificationConf `yaml:"conversationSetPrivate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *configStruct) GetServiceNames() []string {
|
func (c *GlobalConfig) GetServiceNames() []string {
|
||||||
return []string{
|
return []string{
|
||||||
c.RpcRegisterName.OpenImUserName,
|
c.RpcRegisterName.OpenImUserName,
|
||||||
c.RpcRegisterName.OpenImFriendName,
|
c.RpcRegisterName.OpenImFriendName,
|
||||||
@ -392,7 +396,7 @@ func (c *configStruct) GetServiceNames() []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *configStruct) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRegistry) error {
|
func (c *GlobalConfig) RegisterConf2Registry(registry discoveryregistry.SvcDiscoveryRegistry) error {
|
||||||
data, err := yaml.Marshal(c)
|
data, err := yaml.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -400,11 +404,11 @@ func (c *configStruct) RegisterConf2Registry(registry discoveryregistry.SvcDisco
|
|||||||
return registry.RegisterConf2Registry(ConfKey, data)
|
return registry.RegisterConf2Registry(ConfKey, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *configStruct) GetConfFromRegistry(registry discoveryregistry.SvcDiscoveryRegistry) ([]byte, error) {
|
func (c *GlobalConfig) GetConfFromRegistry(registry discoveryregistry.SvcDiscoveryRegistry) ([]byte, error) {
|
||||||
return registry.GetConfFromRegistry(ConfKey)
|
return registry.GetConfFromRegistry(ConfKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *configStruct) EncodeConfig() []byte {
|
func (c *GlobalConfig) EncodeConfig() []byte {
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
if err := yaml.NewEncoder(buf).Encode(c); err != nil {
|
if err := yaml.NewEncoder(buf).Encode(c); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -21,10 +21,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
"github.com/openimsdk/open-im-server/v3/pkg/msgprocessor"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
"github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed version
|
//go:embed version
|
||||||
@ -36,38 +36,32 @@ const (
|
|||||||
DefaultFolderPath = "../config/"
|
DefaultFolderPath = "../config/"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetDefaultConfigPath returns the absolute path to the default configuration directory
|
// return absolude path join ../config/, this is k8s container config path.
|
||||||
// relative to the executable's location. It is intended for use in Kubernetes container configurations.
|
func GetDefaultConfigPath() string {
|
||||||
// Errors are returned to the caller to allow for flexible error handling.
|
|
||||||
func GetDefaultConfigPath() (string, error) {
|
|
||||||
executablePath, err := os.Executable()
|
executablePath, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errs.Wrap(err, "failed to get executable path")
|
fmt.Println("GetDefaultConfigPath error:", err.Error())
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the config path as a directory relative to the executable's location
|
|
||||||
configPath, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../config/"))
|
configPath, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../config/"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errs.Wrap(err, "failed to get output directory")
|
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
return configPath, nil
|
return configPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProjectRoot returns the absolute path of the project root directory by navigating up from the directory
|
// getProjectRoot returns the absolute path of the project root directory.
|
||||||
// containing the executable. It provides a detailed error if the path cannot be determined.
|
func GetProjectRoot() string {
|
||||||
func GetProjectRoot() (string, error) {
|
executablePath, _ := os.Executable()
|
||||||
executablePath, err := os.Executable()
|
|
||||||
if err != nil {
|
|
||||||
return "", errs.Wrap(err, "failed to retrieve executable path")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to compute the project root by navigating up from the executable's directory
|
|
||||||
projectRoot, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../../../../.."))
|
projectRoot, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../../../../.."))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
return projectRoot
|
||||||
return projectRoot, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
||||||
@ -93,62 +87,41 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options {
|
|||||||
// If the specified config file does not exist, it attempts to load from the project's default "config" directory.
|
// If the specified config file does not exist, it attempts to load from the project's default "config" directory.
|
||||||
// It logs informative messages regarding the configuration path being used.
|
// It logs informative messages regarding the configuration path being used.
|
||||||
func initConfig(config any, configName, configFolderPath string) error {
|
func initConfig(config any, configName, configFolderPath string) error {
|
||||||
configFilePath := filepath.Join(configFolderPath, configName)
|
configFolderPath = filepath.Join(configFolderPath, configName)
|
||||||
_, err := os.Stat(configFilePath)
|
_, err := os.Stat(configFolderPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return errs.Wrap(err, fmt.Sprintf("failed to check existence of config file at path: %s", configFilePath))
|
fmt.Println("stat config path error:", err.Error())
|
||||||
|
return fmt.Errorf("stat config path error: %w", err)
|
||||||
}
|
}
|
||||||
var projectRoot string
|
configFolderPath = filepath.Join(GetProjectRoot(), "config", configName)
|
||||||
projectRoot, err = GetProjectRoot()
|
fmt.Println("flag's path,enviment's path,default path all is not exist,using project path:", configFolderPath)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
configFilePath = filepath.Join(projectRoot, "config", configName)
|
|
||||||
fmt.Printf("Configuration file not found at specified path. Falling back to project path: %s\n", configFilePath)
|
|
||||||
}
|
}
|
||||||
|
data, err := os.ReadFile(configFolderPath)
|
||||||
data, err := os.ReadFile(configFilePath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Wrap and return the error if reading the configuration file fails.
|
return fmt.Errorf("read file error: %w", err)
|
||||||
return errs.Wrap(err, fmt.Sprintf("failed to read configuration file at path: %s", configFilePath))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = yaml.Unmarshal(data, config); err != nil {
|
if err = yaml.Unmarshal(data, config); err != nil {
|
||||||
// Wrap and return the error if unmarshalling the YAML configuration fails.
|
return fmt.Errorf("unmarshal yaml error: %w", err)
|
||||||
return errs.Wrap(err, "failed to unmarshal YAML configuration")
|
|
||||||
}
|
}
|
||||||
|
fmt.Println("The path of the configuration file to start the process:", configFolderPath)
|
||||||
|
|
||||||
fmt.Printf("Configuration file loaded successfully from path: %s\n", configFilePath)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitConfig initializes the application configuration by loading it from a specified folder path.
|
func InitConfig(config *GlobalConfig, configFolderPath string) error {
|
||||||
// If the folder path is not provided, it attempts to use the OPENIMCONFIG environment variable,
|
|
||||||
// and as a fallback, it uses the default configuration path. It loads both the main configuration
|
|
||||||
// and notification configuration, wrapping errors for better context.
|
|
||||||
func InitConfig(configFolderPath string) error {
|
|
||||||
// Use the provided config folder path, or fallback to environment variable or default path
|
|
||||||
if configFolderPath == "" {
|
if configFolderPath == "" {
|
||||||
configFolderPath = os.Getenv("OPENIMCONFIG")
|
envConfigPath := os.Getenv("OPENIMCONFIG")
|
||||||
if configFolderPath == "" {
|
if envConfigPath != "" {
|
||||||
var err error
|
configFolderPath = envConfigPath
|
||||||
configFolderPath, err = GetDefaultConfigPath()
|
} else {
|
||||||
if err != nil {
|
configFolderPath = GetDefaultConfigPath()
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the main configuration
|
if err := initConfig(config, FileName, configFolderPath); err != nil {
|
||||||
if err := initConfig(&Config, FileName, configFolderPath); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the notification configuration
|
return initConfig(&config.Notification, NotificationFileName, configFolderPath)
|
||||||
if err := initConfig(&Config.Notification, NotificationFileName, configFolderPath); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -103,13 +103,14 @@ func TestInitConfig(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
|
config *GlobalConfig
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
// TODO: Add test cases.
|
// TODO: Add test cases.
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if err := InitConfig(tt.args.configFolderPath); (err != nil) != tt.wantErr {
|
if err := InitConfig(tt.config, tt.args.configFolderPath); (err != nil) != tt.wantErr {
|
||||||
t.Errorf("InitConfig() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("InitConfig() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
42
pkg/common/db/cache/init_redis.go
vendored
42
pkg/common/db/cache/init_redis.go
vendored
@ -38,34 +38,34 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewRedis Initialize redis connection.
|
// NewRedis Initialize redis connection.
|
||||||
func NewRedis() (redis.UniversalClient, error) {
|
func NewRedis(config *config.GlobalConfig) (redis.UniversalClient, error) {
|
||||||
if redisClient != nil {
|
if redisClient != nil {
|
||||||
return redisClient, nil
|
return redisClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read configuration from environment variables
|
// Read configuration from environment variables
|
||||||
overrideConfigFromEnv()
|
overrideConfigFromEnv(config)
|
||||||
|
|
||||||
if len(config.Config.Redis.Address) == 0 {
|
if len(config.Redis.Address) == 0 {
|
||||||
return nil, errs.Wrap(errors.New("redis address is empty"), "Redis configuration error")
|
return nil, errs.Wrap(errors.New("redis address is empty"))
|
||||||
}
|
}
|
||||||
specialerror.AddReplace(redis.Nil, errs.ErrRecordNotFound)
|
specialerror.AddReplace(redis.Nil, errs.ErrRecordNotFound)
|
||||||
var rdb redis.UniversalClient
|
var rdb redis.UniversalClient
|
||||||
if len(config.Config.Redis.Address) > 1 || config.Config.Redis.ClusterMode {
|
if len(config.Redis.Address) > 1 || config.Redis.ClusterMode {
|
||||||
rdb = redis.NewClusterClient(&redis.ClusterOptions{
|
rdb = redis.NewClusterClient(&redis.ClusterOptions{
|
||||||
Addrs: config.Config.Redis.Address,
|
Addrs: config.Redis.Address,
|
||||||
Username: config.Config.Redis.Username,
|
Username: config.Redis.Username,
|
||||||
Password: config.Config.Redis.Password, // no password set
|
Password: config.Redis.Password, // no password set
|
||||||
PoolSize: 50,
|
PoolSize: 50,
|
||||||
MaxRetries: maxRetry,
|
MaxRetries: maxRetry,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
rdb = redis.NewClient(&redis.Options{
|
rdb = redis.NewClient(&redis.Options{
|
||||||
Addr: config.Config.Redis.Address[0],
|
Addr: config.Redis.Address[0],
|
||||||
Username: config.Config.Redis.Username,
|
Username: config.Redis.Username,
|
||||||
Password: config.Config.Redis.Password, // no password set
|
Password: config.Redis.Password,
|
||||||
DB: 0, // use default DB
|
DB: 0, // use default DB
|
||||||
PoolSize: 100, // connection pool size
|
PoolSize: 100, // connection pool size
|
||||||
MaxRetries: maxRetry,
|
MaxRetries: maxRetry,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -75,33 +75,33 @@ func NewRedis() (redis.UniversalClient, error) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
err = rdb.Ping(ctx).Err()
|
err = rdb.Ping(ctx).Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
uriFormat := "address:%v, username:%s, clusterMode:%t, enablePipeline:%t"
|
errMsg := fmt.Sprintf("address:%s, username:%s, password:%s, clusterMode:%t, enablePipeline:%t", config.Redis.Address, config.Redis.Username,
|
||||||
errMsg := fmt.Sprintf(uriFormat, config.Config.Redis.Address, config.Config.Redis.Username, config.Config.Redis.ClusterMode, config.Config.Redis.EnablePipeline)
|
config.Redis.Password, config.Redis.ClusterMode, config.Redis.EnablePipeline)
|
||||||
return nil, errs.Wrap(err, "Redis connection failed: %s", errMsg)
|
return nil, errs.Wrap(err, errMsg)
|
||||||
}
|
}
|
||||||
redisClient = rdb
|
redisClient = rdb
|
||||||
return rdb, err
|
return rdb, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// overrideConfigFromEnv overrides configuration fields with environment variables if present.
|
// overrideConfigFromEnv overrides configuration fields with environment variables if present.
|
||||||
func overrideConfigFromEnv() {
|
func overrideConfigFromEnv(config *config.GlobalConfig) {
|
||||||
if envAddr := os.Getenv("REDIS_ADDRESS"); envAddr != "" {
|
if envAddr := os.Getenv("REDIS_ADDRESS"); envAddr != "" {
|
||||||
if envPort := os.Getenv("REDIS_PORT"); envPort != "" {
|
if envPort := os.Getenv("REDIS_PORT"); envPort != "" {
|
||||||
addresses := strings.Split(envAddr, ",")
|
addresses := strings.Split(envAddr, ",")
|
||||||
for i, addr := range addresses {
|
for i, addr := range addresses {
|
||||||
addresses[i] = addr + ":" + envPort
|
addresses[i] = addr + ":" + envPort
|
||||||
}
|
}
|
||||||
config.Config.Redis.Address = addresses
|
config.Redis.Address = addresses
|
||||||
} else {
|
} else {
|
||||||
config.Config.Redis.Address = strings.Split(envAddr, ",")
|
config.Redis.Address = strings.Split(envAddr, ",")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if envUser := os.Getenv("REDIS_USERNAME"); envUser != "" {
|
if envUser := os.Getenv("REDIS_USERNAME"); envUser != "" {
|
||||||
config.Config.Redis.Username = envUser
|
config.Redis.Username = envUser
|
||||||
}
|
}
|
||||||
|
|
||||||
if envPass := os.Getenv("REDIS_PASSWORD"); envPass != "" {
|
if envPass := os.Getenv("REDIS_PASSWORD"); envPass != "" {
|
||||||
config.Config.Redis.Password = envPass
|
config.Redis.Password = envPass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
pkg/common/db/cache/meta_cache.go
vendored
19
pkg/common/db/cache/meta_cache.go
vendored
@ -18,13 +18,16 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/mw/specialerror"
|
||||||
|
|
||||||
|
"github.com/dtm-labs/rockscache"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mw/specialerror"
|
|
||||||
"github.com/OpenIMSDK/tools/utils"
|
"github.com/OpenIMSDK/tools/utils"
|
||||||
"github.com/dtm-labs/rockscache"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -128,7 +131,7 @@ func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key strin
|
|||||||
v, err := rcClient.Fetch2(ctx, key, expire, func() (s string, err error) {
|
v, err := rcClient.Fetch2(ctx, key, expire, func() (s string, err error) {
|
||||||
t, err = fn(ctx)
|
t, err = fn(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errs.Wrap(err)
|
||||||
}
|
}
|
||||||
bs, err := json.Marshal(t)
|
bs, err := json.Marshal(t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -139,7 +142,7 @@ func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key strin
|
|||||||
return string(bs), nil
|
return string(bs), nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return t, err
|
return t, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
if write {
|
if write {
|
||||||
return t, nil
|
return t, nil
|
||||||
@ -149,8 +152,8 @@ func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key strin
|
|||||||
}
|
}
|
||||||
err = json.Unmarshal([]byte(v), &t)
|
err = json.Unmarshal([]byte(v), &t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(ctx, "cache json.Unmarshal failed", err, "key", key, "value", v, "expire", expire)
|
errInfo := fmt.Sprintf("cache json.Unmarshal failed, key:%s, value:%s, expire:%s", key, v, expire)
|
||||||
return t, errs.Wrap(err, "unmarshal failed")
|
return t, errs.Wrap(err, errInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return t, nil
|
return t, nil
|
||||||
@ -203,7 +206,7 @@ func batchGetCache2[T any, K comparable](
|
|||||||
fns func(ctx context.Context, key K) (T, error),
|
fns func(ctx context.Context, key K) (T, error),
|
||||||
) ([]T, error) {
|
) ([]T, error) {
|
||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil, nil
|
return nil, errs.ErrArgs.Wrap("groupID is empty")
|
||||||
}
|
}
|
||||||
res := make([]T, 0, len(keys))
|
res := make([]T, 0, len(keys))
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
@ -214,7 +217,7 @@ func batchGetCache2[T any, K comparable](
|
|||||||
if errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err))) {
|
if errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err))) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, errs.Wrap(err)
|
||||||
}
|
}
|
||||||
res = append(res, val)
|
res = append(res, val)
|
||||||
}
|
}
|
||||||
|
23
pkg/common/db/cache/msg.go
vendored
23
pkg/common/db/cache/msg.go
vendored
@ -121,13 +121,14 @@ type MsgModel interface {
|
|||||||
UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error
|
UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMsgCacheModel(client redis.UniversalClient) MsgModel {
|
func NewMsgCacheModel(client redis.UniversalClient, config *config.GlobalConfig) MsgModel {
|
||||||
return &msgCache{rdb: client}
|
return &msgCache{rdb: client, config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
type msgCache struct {
|
type msgCache struct {
|
||||||
metaCache
|
metaCache
|
||||||
rdb redis.UniversalClient
|
rdb redis.UniversalClient
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgCache) getMaxSeqKey(conversationID string) string {
|
func (c *msgCache) getMaxSeqKey(conversationID string) string {
|
||||||
@ -315,7 +316,7 @@ func (c *msgCache) allMessageCacheKey(conversationID string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgCache) GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsgs []*sdkws.MsgData, failedSeqs []int64, err error) {
|
func (c *msgCache) GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsgs []*sdkws.MsgData, failedSeqs []int64, err error) {
|
||||||
if config.Config.Redis.EnablePipeline {
|
if c.config.Redis.EnablePipeline {
|
||||||
return c.PipeGetMessagesBySeq(ctx, conversationID, seqs)
|
return c.PipeGetMessagesBySeq(ctx, conversationID, seqs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +417,7 @@ func (c *msgCache) ParallelGetMessagesBySeq(ctx context.Context, conversationID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgCache) SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) {
|
func (c *msgCache) SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) {
|
||||||
if config.Config.Redis.EnablePipeline {
|
if c.config.Redis.EnablePipeline {
|
||||||
return c.PipeSetMessageToCache(ctx, conversationID, msgs)
|
return c.PipeSetMessageToCache(ctx, conversationID, msgs)
|
||||||
}
|
}
|
||||||
return c.ParallelSetMessageToCache(ctx, conversationID, msgs)
|
return c.ParallelSetMessageToCache(ctx, conversationID, msgs)
|
||||||
@ -431,7 +432,7 @@ func (c *msgCache) PipeSetMessageToCache(ctx context.Context, conversationID str
|
|||||||
}
|
}
|
||||||
|
|
||||||
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
||||||
_ = pipe.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second)
|
_ = pipe.Set(ctx, key, s, time.Duration(c.config.MsgCacheTimeout)*time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
results, err := pipe.Exec(ctx)
|
results, err := pipe.Exec(ctx)
|
||||||
@ -461,7 +462,7 @@ func (c *msgCache) ParallelSetMessageToCache(ctx context.Context, conversationID
|
|||||||
}
|
}
|
||||||
|
|
||||||
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
key := c.getMessageCacheKey(conversationID, msg.Seq)
|
||||||
if err := c.rdb.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
if err := c.rdb.Set(ctx, key, s, time.Duration(c.config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -496,10 +497,10 @@ func (c *msgCache) UserDeleteMsgs(ctx context.Context, conversationID string, se
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
if err := c.rdb.Expire(ctx, delUserListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
if err := c.rdb.Expire(ctx, delUserListKey, time.Duration(c.config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
if err := c.rdb.Expire(ctx, userDelListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
if err := c.rdb.Expire(ctx, userDelListKey, time.Duration(c.config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -604,7 +605,7 @@ func (c *msgCache) DelUserDeleteMsgsList(ctx context.Context, conversationID str
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *msgCache) DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error {
|
func (c *msgCache) DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error {
|
||||||
if config.Config.Redis.EnablePipeline {
|
if c.config.Redis.EnablePipeline {
|
||||||
return c.PipeDeleteMessages(ctx, conversationID, seqs)
|
return c.PipeDeleteMessages(ctx, conversationID, seqs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,7 +687,7 @@ func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []in
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
if err := c.rdb.Set(ctx, key, s, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
if err := c.rdb.Set(ctx, key, s, time.Duration(c.config.MsgCacheTimeout)*time.Second).Err(); err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
pkg/common/db/cache/user.go
vendored
32
pkg/common/db/cache/user.go
vendored
@ -22,12 +22,16 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/log"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/user"
|
"github.com/OpenIMSDK/protocol/user"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
|
||||||
"github.com/dtm-labs/rockscache"
|
"github.com/dtm-labs/rockscache"
|
||||||
relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
|
||||||
"github.com/redis/go-redis/v9"
|
"github.com/redis/go-redis/v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -62,7 +66,11 @@ type UserCacheRedis struct {
|
|||||||
rcClient *rockscache.Client
|
rcClient *rockscache.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserCacheRedis(rdb redis.UniversalClient, userDB relationtb.UserModelInterface, options rockscache.Options) UserCache {
|
func NewUserCacheRedis(
|
||||||
|
rdb redis.UniversalClient,
|
||||||
|
userDB relationtb.UserModelInterface,
|
||||||
|
options rockscache.Options,
|
||||||
|
) UserCache {
|
||||||
rcClient := rockscache.NewClient(rdb, options)
|
rcClient := rockscache.NewClient(rdb, options)
|
||||||
|
|
||||||
return &UserCacheRedis{
|
return &UserCacheRedis{
|
||||||
@ -193,13 +201,13 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu
|
|||||||
Status: constant.Online,
|
Status: constant.Online,
|
||||||
PlatformIDs: []int32{platformID},
|
PlatformIDs: []int32{platformID},
|
||||||
}
|
}
|
||||||
jsonData, err2 := json.Marshal(&onlineStatus)
|
jsonData, err := json.Marshal(&onlineStatus)
|
||||||
if err2 != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err2)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
_, err2 = u.rdb.HSet(ctx, key, userID, string(jsonData)).Result()
|
_, err = u.rdb.HSet(ctx, key, userID, string(jsonData)).Result()
|
||||||
if err2 != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err2)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
u.rdb.Expire(ctx, key, userOlineStatusExpireTime)
|
u.rdb.Expire(ctx, key, userOlineStatusExpireTime)
|
||||||
|
|
||||||
@ -273,9 +281,9 @@ func (u *UserCacheRedis) refreshStatusOffline(ctx context.Context, userID string
|
|||||||
func (u *UserCacheRedis) refreshStatusOnline(ctx context.Context, userID string, platformID int32, isNil bool, err error, result, key string) error {
|
func (u *UserCacheRedis) refreshStatusOnline(ctx context.Context, userID string, platformID int32, isNil bool, err error, result, key string) error {
|
||||||
var onlineStatus user.OnlineStatus
|
var onlineStatus user.OnlineStatus
|
||||||
if !isNil {
|
if !isNil {
|
||||||
err2 := json.Unmarshal([]byte(result), &onlineStatus)
|
err := json.Unmarshal([]byte(result), &onlineStatus)
|
||||||
if err2 != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err, "json.Unmarshal failed")
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
onlineStatus.PlatformIDs = RemoveRepeatedElementsInList(append(onlineStatus.PlatformIDs, platformID))
|
onlineStatus.PlatformIDs = RemoveRepeatedElementsInList(append(onlineStatus.PlatformIDs, platformID))
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,6 +16,7 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
@ -33,14 +34,14 @@ type AuthDatabase interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type authDatabase struct {
|
type authDatabase struct {
|
||||||
cache cache.MsgModel
|
cache cache.MsgModel
|
||||||
|
|
||||||
accessSecret string
|
accessSecret string
|
||||||
accessExpire int64
|
accessExpire int64
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthDatabase(cache cache.MsgModel, accessSecret string, accessExpire int64) AuthDatabase {
|
func NewAuthDatabase(cache cache.MsgModel, accessSecret string, accessExpire int64, config *config.GlobalConfig) AuthDatabase {
|
||||||
return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire}
|
return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire, config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the result is empty.
|
// If the result is empty.
|
||||||
@ -56,7 +57,7 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
|||||||
}
|
}
|
||||||
var deleteTokenKey []string
|
var deleteTokenKey []string
|
||||||
for k, v := range tokens {
|
for k, v := range tokens {
|
||||||
_, err = tokenverify.GetClaimFromToken(k, authverify.Secret())
|
_, err = tokenverify.GetClaimFromToken(k, authverify.Secret(a.config.Secret))
|
||||||
if err != nil || v != constant.NormalToken {
|
if err != nil || v != constant.NormalToken {
|
||||||
deleteTokenKey = append(deleteTokenKey, k)
|
deleteTokenKey = append(deleteTokenKey, k)
|
||||||
}
|
}
|
||||||
|
@ -120,16 +120,33 @@ type CommonMsgDatabase interface {
|
|||||||
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
|
ConvertMsgsDocLen(ctx context.Context, conversationIDs []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCommonMsgDatabase(msgDocModel unrelationtb.MsgDocModelInterface, cacheModel cache.MsgModel) (CommonMsgDatabase, error) {
|
func NewCommonMsgDatabase(msgDocModel unrelationtb.MsgDocModelInterface, cacheModel cache.MsgModel, config *config.GlobalConfig) (CommonMsgDatabase, error) {
|
||||||
producerToRedis, err := kafka.NewKafkaProducer(config.Config.Kafka.Addr, config.Config.Kafka.LatestMsgToRedis.Topic)
|
producerConfig := &kafka.ProducerConfig{
|
||||||
|
ProducerAck: config.Kafka.ProducerAck,
|
||||||
|
CompressType: config.Kafka.CompressType,
|
||||||
|
Username: config.Kafka.Username,
|
||||||
|
Password: config.Kafka.Password,
|
||||||
|
}
|
||||||
|
|
||||||
|
var tlsConfig *kafka.TLSConfig
|
||||||
|
if config.Kafka.TLS != nil {
|
||||||
|
tlsConfig = &kafka.TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
producerToRedis, err := kafka.NewKafkaProducer(config.Kafka.Addr, config.Kafka.LatestMsgToRedis.Topic, producerConfig, tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
producerToMongo, err := kafka.NewKafkaProducer(config.Config.Kafka.Addr, config.Config.Kafka.MsgToMongo.Topic)
|
producerToMongo, err := kafka.NewKafkaProducer(config.Kafka.Addr, config.Kafka.MsgToMongo.Topic, producerConfig, tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
producerToPush, err := kafka.NewKafkaProducer(config.Config.Kafka.Addr, config.Config.Kafka.MsgToPush.Topic)
|
producerToPush, err := kafka.NewKafkaProducer(config.Kafka.Addr, config.Kafka.MsgToPush.Topic, producerConfig, tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -142,10 +159,10 @@ func NewCommonMsgDatabase(msgDocModel unrelationtb.MsgDocModelInterface, cacheMo
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database) (CommonMsgDatabase, error) {
|
func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database, config *config.GlobalConfig) (CommonMsgDatabase, error) {
|
||||||
cacheModel := cache.NewMsgCacheModel(rdb)
|
cacheModel := cache.NewMsgCacheModel(rdb, config)
|
||||||
msgDocModel := unrelation.NewMsgMongoDriver(database)
|
msgDocModel := unrelation.NewMsgMongoDriver(database)
|
||||||
return NewCommonMsgDatabase(msgDocModel, cacheModel)
|
return NewCommonMsgDatabase(msgDocModel, cacheModel, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
type commonMsgDatabase struct {
|
type commonMsgDatabase struct {
|
||||||
@ -397,9 +414,9 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
|
|||||||
log.ZError(ctx, "db.cache.SetMaxSeq error", err, "conversationID", conversationID)
|
log.ZError(ctx, "db.cache.SetMaxSeq error", err, "conversationID", conversationID)
|
||||||
prommetrics.SeqSetFailedCounter.Inc()
|
prommetrics.SeqSetFailedCounter.Inc()
|
||||||
}
|
}
|
||||||
err2 := db.cache.SetHasReadSeqs(ctx, conversationID, userSeqMap)
|
err = db.cache.SetHasReadSeqs(ctx, conversationID, userSeqMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ZError(ctx, "SetHasReadSeqs error", err2, "userSeqMap", userSeqMap, "conversationID", conversationID)
|
log.ZError(ctx, "SetHasReadSeqs error", err, "userSeqMap", userSeqMap, "conversationID", conversationID)
|
||||||
prommetrics.SeqSetFailedCounter.Inc()
|
prommetrics.SeqSetFailedCounter.Inc()
|
||||||
}
|
}
|
||||||
return lastMaxSeq, isNew, errs.Wrap(err)
|
return lastMaxSeq, isNew, errs.Wrap(err)
|
||||||
|
@ -33,27 +33,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test_BatchInsertChat2DB(t *testing.T) {
|
func Test_BatchInsertChat2DB(t *testing.T) {
|
||||||
config.Config.Mongo.Address = []string{"192.168.44.128:37017"}
|
conf := config.NewGlobalConfig()
|
||||||
// config.Config.Mongo.Timeout = 60
|
conf.Mongo.Address = []string{"192.168.44.128:37017"}
|
||||||
config.Config.Mongo.Database = "openIM"
|
// conf.Mongo.Timeout = 60
|
||||||
// config.Config.Mongo.Source = "admin"
|
conf.Mongo.Database = "openIM"
|
||||||
config.Config.Mongo.Username = "root"
|
// conf.Mongo.Source = "admin"
|
||||||
config.Config.Mongo.Password = "openIM123"
|
conf.Mongo.Username = "root"
|
||||||
config.Config.Mongo.MaxPoolSize = 100
|
conf.Mongo.Password = "openIM123"
|
||||||
config.Config.RetainChatRecords = 3650
|
conf.Mongo.MaxPoolSize = 100
|
||||||
config.Config.ChatRecordsClearTime = "0 2 * * 3"
|
conf.RetainChatRecords = 3650
|
||||||
|
conf.ChatRecordsClearTime = "0 2 * * 3"
|
||||||
|
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err = mongo.GetDatabase().Client().Ping(context.Background(), nil)
|
err = mongo.GetDatabase(conf.Mongo.Database).Client().Ping(context.Background(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
db := &commonMsgDatabase{
|
db := &commonMsgDatabase{
|
||||||
msgDocDatabase: unrelation.NewMsgMongoDriver(mongo.GetDatabase()),
|
msgDocDatabase: unrelation.NewMsgMongoDriver(mongo.GetDatabase(conf.Mongo.Database)),
|
||||||
}
|
}
|
||||||
|
|
||||||
//ctx := context.Background()
|
//ctx := context.Background()
|
||||||
@ -70,7 +71,7 @@ func Test_BatchInsertChat2DB(t *testing.T) {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
_ = db.BatchInsertChat2DB
|
_ = db.BatchInsertChat2DB
|
||||||
c := mongo.GetDatabase().Collection("msg")
|
c := mongo.GetDatabase(conf.Mongo.Database).Collection("msg")
|
||||||
|
|
||||||
ch := make(chan int)
|
ch := make(chan int)
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
@ -144,26 +145,27 @@ func Test_BatchInsertChat2DB(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetDB() *commonMsgDatabase {
|
func GetDB() *commonMsgDatabase {
|
||||||
config.Config.Mongo.Address = []string{"203.56.175.233:37017"}
|
conf := config.NewGlobalConfig()
|
||||||
// config.Config.Mongo.Timeout = 60
|
conf.Mongo.Address = []string{"203.56.175.233:37017"}
|
||||||
config.Config.Mongo.Database = "openim_v3"
|
// conf.Mongo.Timeout = 60
|
||||||
// config.Config.Mongo.Source = "admin"
|
conf.Mongo.Database = "openim_v3"
|
||||||
config.Config.Mongo.Username = "root"
|
// conf.Mongo.Source = "admin"
|
||||||
config.Config.Mongo.Password = "openIM123"
|
conf.Mongo.Username = "root"
|
||||||
config.Config.Mongo.MaxPoolSize = 100
|
conf.Mongo.Password = "openIM123"
|
||||||
config.Config.RetainChatRecords = 3650
|
conf.Mongo.MaxPoolSize = 100
|
||||||
config.Config.ChatRecordsClearTime = "0 2 * * 3"
|
conf.RetainChatRecords = 3650
|
||||||
|
conf.ChatRecordsClearTime = "0 2 * * 3"
|
||||||
|
|
||||||
mongo, err := unrelation.NewMongo()
|
mongo, err := unrelation.NewMongo(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
err = mongo.GetDatabase().Client().Ping(context.Background(), nil)
|
err = mongo.GetDatabase(conf.Mongo.Database).Client().Ping(context.Background(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return &commonMsgDatabase{
|
return &commonMsgDatabase{
|
||||||
msgDocDatabase: unrelation.NewMsgMongoDriver(mongo.GetDatabase()),
|
msgDocDatabase: unrelation.NewMsgMongoDriver(mongo.GetDatabase(conf.Mongo.Database)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,275 +0,0 @@
|
|||||||
// Copyright © 2023 OpenIM. All rights reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// docURL: https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
|
||||||
sdk "github.com/aws/aws-sdk-go/service/s3"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
minPartSize int64 = 1024 * 1024 * 1 // 1MB
|
|
||||||
maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
|
|
||||||
maxNumSize int64 = 10000
|
|
||||||
)
|
|
||||||
|
|
||||||
// const (
|
|
||||||
// imagePng = "png"
|
|
||||||
// imageJpg = "jpg"
|
|
||||||
// imageJpeg = "jpeg"
|
|
||||||
// imageGif = "gif"
|
|
||||||
// imageWebp = "webp"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// const successCode = http.StatusOK
|
|
||||||
|
|
||||||
// const (
|
|
||||||
// videoSnapshotImagePng = "png"
|
|
||||||
// videoSnapshotImageJpg = "jpg"
|
|
||||||
// )
|
|
||||||
|
|
||||||
func NewAWS() (s3.Interface, error) {
|
|
||||||
conf := config.Config.Object.Aws
|
|
||||||
credential := credentials.NewStaticCredentials(
|
|
||||||
conf.AccessKeyID, // accessKey
|
|
||||||
conf.AccessKeySecret, // secretKey
|
|
||||||
"") // stoken
|
|
||||||
|
|
||||||
sess, err := session.NewSession(&aws.Config{
|
|
||||||
Region: aws.String(conf.Region), // The area where the bucket is located
|
|
||||||
Credentials: credential,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Aws{
|
|
||||||
bucket: conf.Bucket,
|
|
||||||
client: sdk.New(sess),
|
|
||||||
credential: credential,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Aws struct {
|
|
||||||
bucket string
|
|
||||||
client *sdk.S3
|
|
||||||
credential *credentials.Credentials
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) Engine() string {
|
|
||||||
return "aws"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) InitiateMultipartUpload(ctx context.Context, name string) (*s3.InitiateMultipartUploadResult, error) {
|
|
||||||
input := &sdk.CreateMultipartUploadInput{
|
|
||||||
Bucket: aws.String(a.bucket), // TODO: To be verified whether it is required
|
|
||||||
Key: aws.String(name),
|
|
||||||
}
|
|
||||||
result, err := a.client.CreateMultipartUploadWithContext(ctx, input)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &s3.InitiateMultipartUploadResult{
|
|
||||||
Bucket: *result.Bucket,
|
|
||||||
Key: *result.Key,
|
|
||||||
UploadID: *result.UploadId,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) CompleteMultipartUpload(ctx context.Context, uploadID string, name string, parts []s3.Part) (*s3.CompleteMultipartUploadResult, error) {
|
|
||||||
sdkParts := make([]*sdk.CompletedPart, len(parts))
|
|
||||||
for i, part := range parts {
|
|
||||||
sdkParts[i] = &sdk.CompletedPart{
|
|
||||||
ETag: aws.String(part.ETag),
|
|
||||||
PartNumber: aws.Int64(int64(part.PartNumber)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
input := &sdk.CompleteMultipartUploadInput{
|
|
||||||
Bucket: aws.String(a.bucket), // TODO: To be verified whether it is required
|
|
||||||
Key: aws.String(name),
|
|
||||||
UploadId: aws.String(uploadID),
|
|
||||||
MultipartUpload: &sdk.CompletedMultipartUpload{
|
|
||||||
Parts: sdkParts,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
result, err := a.client.CompleteMultipartUploadWithContext(ctx, input)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &s3.CompleteMultipartUploadResult{
|
|
||||||
Location: *result.Location,
|
|
||||||
Bucket: *result.Bucket,
|
|
||||||
Key: *result.Key,
|
|
||||||
ETag: *result.ETag,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) PartSize(ctx context.Context, size int64) (int64, error) {
|
|
||||||
if size <= 0 {
|
|
||||||
return 0, errors.New("size must be greater than 0")
|
|
||||||
}
|
|
||||||
if size > maxPartSize*maxNumSize {
|
|
||||||
return 0, fmt.Errorf("AWS size must be less than the maximum allowed limit")
|
|
||||||
}
|
|
||||||
if size <= minPartSize*maxNumSize {
|
|
||||||
return minPartSize, nil
|
|
||||||
}
|
|
||||||
partSize := size / maxNumSize
|
|
||||||
if size%maxNumSize != 0 {
|
|
||||||
partSize++
|
|
||||||
}
|
|
||||||
return partSize, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) DeleteObject(ctx context.Context, name string) error {
|
|
||||||
_, err := a.client.DeleteObjectWithContext(ctx, &sdk.DeleteObjectInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(name),
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyObjectInfo, error) {
|
|
||||||
result, err := a.client.CopyObjectWithContext(ctx, &sdk.CopyObjectInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(dst),
|
|
||||||
CopySource: aws.String(src),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &s3.CopyObjectInfo{
|
|
||||||
ETag: *result.CopyObjectResult.ETag,
|
|
||||||
Key: dst,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) IsNotFound(err error) bool {
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
switch aerr.Code() {
|
|
||||||
case sdk.ErrCodeNoSuchKey:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error {
|
|
||||||
_, err := a.client.AbortMultipartUploadWithContext(ctx, &sdk.AbortMultipartUploadInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(name),
|
|
||||||
UploadId: aws.String(uploadID),
|
|
||||||
})
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) ListUploadedParts(ctx context.Context, uploadID string, name string, partNumberMarker int, maxParts int) (*s3.ListUploadedPartsResult, error) {
|
|
||||||
result, err := a.client.ListPartsWithContext(ctx, &sdk.ListPartsInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(name),
|
|
||||||
UploadId: aws.String(uploadID),
|
|
||||||
MaxParts: aws.Int64(int64(maxParts)),
|
|
||||||
PartNumberMarker: aws.Int64(int64(partNumberMarker)),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
parts := make([]s3.UploadedPart, len(result.Parts))
|
|
||||||
for i, part := range result.Parts {
|
|
||||||
parts[i] = s3.UploadedPart{
|
|
||||||
PartNumber: int(*part.PartNumber),
|
|
||||||
LastModified: *part.LastModified,
|
|
||||||
Size: *part.Size,
|
|
||||||
ETag: *part.ETag,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &s3.ListUploadedPartsResult{
|
|
||||||
Key: *result.Key,
|
|
||||||
UploadID: *result.UploadId,
|
|
||||||
NextPartNumberMarker: int(*result.NextPartNumberMarker),
|
|
||||||
MaxParts: int(*result.MaxParts),
|
|
||||||
UploadedParts: parts,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) PartLimit() *s3.PartLimit {
|
|
||||||
return &s3.PartLimit{
|
|
||||||
MinPartSize: minPartSize,
|
|
||||||
MaxPartSize: maxPartSize,
|
|
||||||
MaxNumSize: maxNumSize,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) PresignedPutObject(ctx context.Context, name string, expire time.Duration) (string, error) {
|
|
||||||
req, _ := a.client.PutObjectRequest(&sdk.PutObjectInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(name),
|
|
||||||
})
|
|
||||||
url, err := req.Presign(expire)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return url, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) {
|
|
||||||
result, err := a.client.GetObjectWithContext(ctx, &sdk.GetObjectInput{
|
|
||||||
Bucket: aws.String(a.bucket),
|
|
||||||
Key: aws.String(name),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
res := &s3.ObjectInfo{
|
|
||||||
Key: name,
|
|
||||||
ETag: *result.ETag,
|
|
||||||
Size: *result.ContentLength,
|
|
||||||
LastModified: *result.LastModified,
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccessURL todo.
|
|
||||||
func (a *Aws) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
|
||||||
// todo
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) {
|
|
||||||
// todo
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Aws) AuthSign(ctx context.Context, uploadID string, name string, expire time.Duration, partNumbers []int) (*s3.AuthSignResult, error) {
|
|
||||||
// todo
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
@ -23,13 +23,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
"github.com/tencentyun/cos-go-sdk-v5"
|
"github.com/tencentyun/cos-go-sdk-v5"
|
||||||
)
|
)
|
||||||
@ -50,13 +50,15 @@ const (
|
|||||||
|
|
||||||
const successCode = http.StatusOK
|
const successCode = http.StatusOK
|
||||||
|
|
||||||
const (
|
type Config struct {
|
||||||
// videoSnapshotImagePng = "png"
|
BucketURL string
|
||||||
// videoSnapshotImageJpg = "jpg"
|
SecretID string
|
||||||
)
|
SecretKey string
|
||||||
|
SessionToken string
|
||||||
|
PublicRead bool
|
||||||
|
}
|
||||||
|
|
||||||
func NewCos() (s3.Interface, error) {
|
func NewCos(conf Config) (s3.Interface, error) {
|
||||||
conf := config.Config.Object.Cos
|
|
||||||
u, err := url.Parse(conf.BucketURL)
|
u, err := url.Parse(conf.BucketURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -69,6 +71,7 @@ func NewCos() (s3.Interface, error) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
return &Cos{
|
return &Cos{
|
||||||
|
publicRead: conf.PublicRead,
|
||||||
copyURL: u.Host + "/",
|
copyURL: u.Host + "/",
|
||||||
client: client,
|
client: client,
|
||||||
credential: client.GetCredential(),
|
credential: client.GetCredential(),
|
||||||
@ -76,6 +79,7 @@ func NewCos() (s3.Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Cos struct {
|
type Cos struct {
|
||||||
|
publicRead bool
|
||||||
copyURL string
|
copyURL string
|
||||||
client *cos.Client
|
client *cos.Client
|
||||||
credential *cos.Credential
|
credential *cos.Credential
|
||||||
@ -226,7 +230,7 @@ func (c *Cos) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cos) IsNotFound(err error) bool {
|
func (c *Cos) IsNotFound(err error) bool {
|
||||||
switch e := err.(type) {
|
switch e := errs.Unwrap(err).(type) {
|
||||||
case *cos.ErrorResponse:
|
case *cos.ErrorResponse:
|
||||||
return e.Response.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
return e.Response.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||||
default:
|
default:
|
||||||
@ -327,7 +331,7 @@ func (c *Cos) AccessURL(ctx context.Context, name string, expire time.Duration,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Duration, opt *cos.PresignedURLOptions) (*url.URL, error) {
|
func (c *Cos) getPresignedURL(ctx context.Context, name string, expire time.Duration, opt *cos.PresignedURLOptions) (*url.URL, error) {
|
||||||
if !config.Config.Object.Cos.PublicRead {
|
if !c.publicRead {
|
||||||
return c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, opt)
|
return c.client.Object.GetPresignedURL(ctx, http.MethodGet, name, c.credential.SecretID, c.credential.SecretKey, expire, opt)
|
||||||
}
|
}
|
||||||
return c.client.Object.GetObjectURL(name), nil
|
return c.client.Object.GetObjectURL(name), nil
|
||||||
|
@ -42,51 +42,79 @@ func ImageWidthHeight(img image.Image) (int, int) {
|
|||||||
return bounds.X, bounds.Y
|
return bounds.X, bounds.Y
|
||||||
}
|
}
|
||||||
|
|
||||||
// resizeImage resizes an image to a specified maximum width and height, maintaining the aspect ratio.
|
|
||||||
// If both maxWidth and maxHeight are set to 0, the original image is returned.
|
|
||||||
// If both are non-zero, the image is scaled to fit within the constraints while maintaining aspect ratio.
|
|
||||||
// If only one of maxWidth or maxHeight is non-zero, the image is scaled accordingly.
|
|
||||||
func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||||
bounds := img.Bounds()
|
bounds := img.Bounds()
|
||||||
imgWidth, imgHeight := bounds.Dx(), bounds.Dy()
|
imgWidth := bounds.Max.X
|
||||||
|
imgHeight := bounds.Max.Y
|
||||||
|
|
||||||
// Return original image if no resizing is needed.
|
// 计算缩放比例
|
||||||
|
scaleWidth := float64(maxWidth) / float64(imgWidth)
|
||||||
|
scaleHeight := float64(maxHeight) / float64(imgHeight)
|
||||||
|
|
||||||
|
// 如果都为0,则不缩放,返回原始图片
|
||||||
if maxWidth == 0 && maxHeight == 0 {
|
if maxWidth == 0 && maxHeight == 0 {
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
var scale float64 = 1
|
// 如果宽度和高度都大于0,则选择较小的缩放比例,以保持宽高比
|
||||||
if maxWidth > 0 && maxHeight > 0 {
|
if maxWidth > 0 && maxHeight > 0 {
|
||||||
scaleWidth := float64(maxWidth) / float64(imgWidth)
|
scale := scaleWidth
|
||||||
scaleHeight := float64(maxHeight) / float64(imgHeight)
|
if scaleHeight < scaleWidth {
|
||||||
// Choose the smaller scale to fit both constraints.
|
scale = scaleHeight
|
||||||
scale = min(scaleWidth, scaleHeight)
|
|
||||||
} else if maxWidth > 0 {
|
|
||||||
scale = float64(maxWidth) / float64(imgWidth)
|
|
||||||
} else if maxHeight > 0 {
|
|
||||||
scale = float64(maxHeight) / float64(imgHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
newWidth := int(float64(imgWidth) * scale)
|
|
||||||
newHeight := int(float64(imgHeight) * scale)
|
|
||||||
|
|
||||||
// Resize the image by creating a new image and manually copying pixels.
|
|
||||||
thumbnail := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight))
|
|
||||||
for y := 0; y < newHeight; y++ {
|
|
||||||
for x := 0; x < newWidth; x++ {
|
|
||||||
srcX := int(float64(x) / scale)
|
|
||||||
srcY := int(float64(y) / scale)
|
|
||||||
thumbnail.Set(x, y, img.At(srcX, srcY))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 计算缩略图尺寸
|
||||||
|
thumbnailWidth := int(float64(imgWidth) * scale)
|
||||||
|
thumbnailHeight := int(float64(imgHeight) * scale)
|
||||||
|
|
||||||
|
// 使用"image"库的Resample方法生成缩略图
|
||||||
|
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||||
|
for y := 0; y < thumbnailHeight; y++ {
|
||||||
|
for x := 0; x < thumbnailWidth; x++ {
|
||||||
|
srcX := int(float64(x) / scale)
|
||||||
|
srcY := int(float64(y) / scale)
|
||||||
|
thumbnail.Set(x, y, img.At(srcX, srcY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnail
|
||||||
}
|
}
|
||||||
|
|
||||||
return thumbnail
|
// 如果只指定了宽度或高度,则根据最大不超过的规则生成缩略图
|
||||||
}
|
if maxWidth > 0 {
|
||||||
|
thumbnailWidth := maxWidth
|
||||||
|
thumbnailHeight := int(float64(imgHeight) * scaleWidth)
|
||||||
|
|
||||||
// min returns the smaller of x or y.
|
// 使用"image"库的Resample方法生成缩略图
|
||||||
func min(x, y float64) float64 {
|
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||||
if x < y {
|
for y := 0; y < thumbnailHeight; y++ {
|
||||||
return x
|
for x := 0; x < thumbnailWidth; x++ {
|
||||||
|
srcX := int(float64(x) / scaleWidth)
|
||||||
|
srcY := int(float64(y) / scaleWidth)
|
||||||
|
thumbnail.Set(x, y, img.At(srcX, srcY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnail
|
||||||
}
|
}
|
||||||
return y
|
|
||||||
|
if maxHeight > 0 {
|
||||||
|
thumbnailWidth := int(float64(imgWidth) * scaleHeight)
|
||||||
|
thumbnailHeight := maxHeight
|
||||||
|
|
||||||
|
// 使用"image"库的Resample方法生成缩略图
|
||||||
|
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||||
|
for y := 0; y < thumbnailHeight; y++ {
|
||||||
|
for x := 0; x < thumbnailWidth; x++ {
|
||||||
|
srcX := int(float64(x) / scaleHeight)
|
||||||
|
srcY := int(float64(y) / scaleHeight)
|
||||||
|
thumbnail.Set(x, y, img.At(srcX, srcY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnail
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认情况下,返回原始图片
|
||||||
|
return img
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -33,7 +34,6 @@ import (
|
|||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||||
"github.com/minio/minio-go/v7/pkg/signer"
|
"github.com/minio/minio-go/v7/pkg/signer"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/cache"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
)
|
)
|
||||||
@ -43,7 +43,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
minPartSize int64 = 1024 * 1024 * 5 // 1MB
|
minPartSize int64 = 1024 * 1024 * 5 // 5MB
|
||||||
maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
|
maxPartSize int64 = 1024 * 1024 * 1024 * 5 // 5GB
|
||||||
maxNumSize int64 = 10000
|
maxNumSize int64 = 10000
|
||||||
)
|
)
|
||||||
@ -57,13 +57,23 @@ const (
|
|||||||
|
|
||||||
const successCode = http.StatusOK
|
const successCode = http.StatusOK
|
||||||
|
|
||||||
func NewMinio(cache cache.MinioCache) (s3.Interface, error) {
|
type Config struct {
|
||||||
u, err := url.Parse(config.Config.Object.Minio.Endpoint)
|
Bucket string
|
||||||
|
Endpoint string
|
||||||
|
AccessKeyID string
|
||||||
|
SecretAccessKey string
|
||||||
|
SessionToken string
|
||||||
|
SignEndpoint string
|
||||||
|
PublicRead bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMinio(cache cache.MinioCache, conf Config) (s3.Interface, error) {
|
||||||
|
u, err := url.Parse(conf.Endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := &minio.Options{
|
opts := &minio.Options{
|
||||||
Creds: credentials.NewStaticV4(config.Config.Object.Minio.AccessKeyID, config.Config.Object.Minio.SecretAccessKey, config.Config.Object.Minio.SessionToken),
|
Creds: credentials.NewStaticV4(conf.AccessKeyID, conf.SecretAccessKey, conf.SessionToken),
|
||||||
Secure: u.Scheme == "https",
|
Secure: u.Scheme == "https",
|
||||||
}
|
}
|
||||||
client, err := minio.New(u.Host, opts)
|
client, err := minio.New(u.Host, opts)
|
||||||
@ -71,26 +81,27 @@ func NewMinio(cache cache.MinioCache) (s3.Interface, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m := &Minio{
|
m := &Minio{
|
||||||
bucket: config.Config.Object.Minio.Bucket,
|
conf: conf,
|
||||||
|
bucket: conf.Bucket,
|
||||||
core: &minio.Core{Client: client},
|
core: &minio.Core{Client: client},
|
||||||
lock: &sync.Mutex{},
|
lock: &sync.Mutex{},
|
||||||
init: false,
|
init: false,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
}
|
}
|
||||||
if config.Config.Object.Minio.SignEndpoint == "" || config.Config.Object.Minio.SignEndpoint == config.Config.Object.Minio.Endpoint {
|
if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint {
|
||||||
m.opts = opts
|
m.opts = opts
|
||||||
m.sign = m.core.Client
|
m.sign = m.core.Client
|
||||||
m.prefix = u.Path
|
m.prefix = u.Path
|
||||||
u.Path = ""
|
u.Path = ""
|
||||||
config.Config.Object.Minio.Endpoint = u.String()
|
conf.Endpoint = u.String()
|
||||||
m.signEndpoint = config.Config.Object.Minio.Endpoint
|
m.signEndpoint = conf.Endpoint
|
||||||
} else {
|
} else {
|
||||||
su, err := url.Parse(config.Config.Object.Minio.SignEndpoint)
|
su, err := url.Parse(conf.SignEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m.opts = &minio.Options{
|
m.opts = &minio.Options{
|
||||||
Creds: credentials.NewStaticV4(config.Config.Object.Minio.AccessKeyID, config.Config.Object.Minio.SecretAccessKey, config.Config.Object.Minio.SessionToken),
|
Creds: credentials.NewStaticV4(conf.AccessKeyID, conf.SecretAccessKey, conf.SessionToken),
|
||||||
Secure: su.Scheme == "https",
|
Secure: su.Scheme == "https",
|
||||||
}
|
}
|
||||||
m.sign, err = minio.New(su.Host, m.opts)
|
m.sign, err = minio.New(su.Host, m.opts)
|
||||||
@ -99,8 +110,8 @@ func NewMinio(cache cache.MinioCache) (s3.Interface, error) {
|
|||||||
}
|
}
|
||||||
m.prefix = su.Path
|
m.prefix = su.Path
|
||||||
su.Path = ""
|
su.Path = ""
|
||||||
config.Config.Object.Minio.SignEndpoint = su.String()
|
conf.SignEndpoint = su.String()
|
||||||
m.signEndpoint = config.Config.Object.Minio.SignEndpoint
|
m.signEndpoint = conf.SignEndpoint
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -111,6 +122,7 @@ func NewMinio(cache cache.MinioCache) (s3.Interface, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Minio struct {
|
type Minio struct {
|
||||||
|
conf Config
|
||||||
bucket string
|
bucket string
|
||||||
signEndpoint string
|
signEndpoint string
|
||||||
location string
|
location string
|
||||||
@ -132,31 +144,30 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
|||||||
if m.init {
|
if m.init {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
conf := config.Config.Object.Minio
|
exists, err := m.core.Client.BucketExists(ctx, m.conf.Bucket)
|
||||||
exists, err := m.core.Client.BucketExists(ctx, conf.Bucket)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check bucket exists error: %w", err)
|
return fmt.Errorf("check bucket exists error: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
if err = m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
if err = m.core.Client.MakeBucket(ctx, m.conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||||
return fmt.Errorf("make bucket error: %w", err)
|
return fmt.Errorf("make bucket error: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if conf.PublicRead {
|
if m.conf.PublicRead {
|
||||||
policy := fmt.Sprintf(
|
policy := fmt.Sprintf(
|
||||||
`{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject","s3:PutObject"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::%s/*"],"Sid": ""}]}`,
|
`{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject","s3:PutObject"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::%s/*"],"Sid": ""}]}`,
|
||||||
conf.Bucket,
|
m.conf.Bucket,
|
||||||
)
|
)
|
||||||
if err = m.core.Client.SetBucketPolicy(ctx, conf.Bucket, policy); err != nil {
|
if err = m.core.Client.SetBucketPolicy(ctx, m.conf.Bucket, policy); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m.location, err = m.core.Client.GetBucketLocation(ctx, conf.Bucket)
|
m.location, err = m.core.Client.GetBucketLocation(ctx, m.conf.Bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func() {
|
func() {
|
||||||
if conf.SignEndpoint == "" || conf.SignEndpoint == conf.Endpoint {
|
if m.conf.SignEndpoint == "" || m.conf.SignEndpoint == m.conf.Endpoint {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -176,7 +187,7 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
|||||||
blc := reflect.ValueOf(m.sign).Elem().FieldByName("bucketLocCache")
|
blc := reflect.ValueOf(m.sign).Elem().FieldByName("bucketLocCache")
|
||||||
vblc := reflect.New(reflect.PtrTo(blc.Type()))
|
vblc := reflect.New(reflect.PtrTo(blc.Type()))
|
||||||
*(*unsafe.Pointer)(vblc.UnsafePointer()) = unsafe.Pointer(blc.UnsafeAddr())
|
*(*unsafe.Pointer)(vblc.UnsafePointer()) = unsafe.Pointer(blc.UnsafeAddr())
|
||||||
vblc.Elem().Elem().Interface().(interface{ Set(string, string) }).Set(conf.Bucket, m.location)
|
vblc.Elem().Elem().Interface().(interface{ Set(string, string) }).Set(m.conf.Bucket, m.location)
|
||||||
}()
|
}()
|
||||||
m.init = true
|
m.init = true
|
||||||
return nil
|
return nil
|
||||||
@ -341,10 +352,7 @@ func (m *Minio) CopyObject(ctx context.Context, src string, dst string) (*s3.Cop
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Minio) IsNotFound(err error) bool {
|
func (m *Minio) IsNotFound(err error) bool {
|
||||||
if err == nil {
|
switch e := errs.Unwrap(err).(type) {
|
||||||
return false
|
|
||||||
}
|
|
||||||
switch e := err.(type) {
|
|
||||||
case minio.ErrorResponse:
|
case minio.ErrorResponse:
|
||||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||||
case *minio.ErrorResponse:
|
case *minio.ErrorResponse:
|
||||||
@ -397,7 +405,7 @@ func (m *Minio) PresignedGetObject(ctx context.Context, name string, expire time
|
|||||||
rawURL *url.URL
|
rawURL *url.URL
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if config.Config.Object.Minio.PublicRead {
|
if m.conf.PublicRead {
|
||||||
rawURL, err = makeTargetURL(m.sign, m.bucket, name, m.location, false, query)
|
rawURL, err = makeTargetURL(m.sign, m.bucket, name, m.location, false, query)
|
||||||
} else {
|
} else {
|
||||||
rawURL, err = m.sign.PresignedGetObject(ctx, m.bucket, name, expire, query)
|
rawURL, err = m.sign.PresignedGetObject(ctx, m.bucket, name, expire, query)
|
||||||
|
@ -32,7 +32,6 @@ import (
|
|||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/db/s3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,13 +51,17 @@ const (
|
|||||||
|
|
||||||
const successCode = http.StatusOK
|
const successCode = http.StatusOK
|
||||||
|
|
||||||
/* const (
|
type Config struct {
|
||||||
videoSnapshotImagePng = "png"
|
Endpoint string
|
||||||
videoSnapshotImageJpg = "jpg"
|
Bucket string
|
||||||
) */
|
BucketURL string
|
||||||
|
AccessKeyID string
|
||||||
|
AccessKeySecret string
|
||||||
|
SessionToken string
|
||||||
|
PublicRead bool
|
||||||
|
}
|
||||||
|
|
||||||
func NewOSS() (s3.Interface, error) {
|
func NewOSS(conf Config) (s3.Interface, error) {
|
||||||
conf := config.Config.Object.Oss
|
|
||||||
if conf.BucketURL == "" {
|
if conf.BucketURL == "" {
|
||||||
return nil, errs.Wrap(errors.New("bucket url is empty"))
|
return nil, errs.Wrap(errors.New("bucket url is empty"))
|
||||||
}
|
}
|
||||||
@ -78,6 +81,7 @@ func NewOSS() (s3.Interface, error) {
|
|||||||
bucket: bucket,
|
bucket: bucket,
|
||||||
credentials: client.Config.GetCredentials(),
|
credentials: client.Config.GetCredentials(),
|
||||||
um: *(*urlMaker)(reflect.ValueOf(bucket.Client.Conn).Elem().FieldByName("url").UnsafePointer()),
|
um: *(*urlMaker)(reflect.ValueOf(bucket.Client.Conn).Elem().FieldByName("url").UnsafePointer()),
|
||||||
|
publicRead: conf.PublicRead,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +90,7 @@ type OSS struct {
|
|||||||
bucket *oss.Bucket
|
bucket *oss.Bucket
|
||||||
credentials oss.Credentials
|
credentials oss.Credentials
|
||||||
um urlMaker
|
um urlMaker
|
||||||
|
publicRead bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSS) Engine() string {
|
func (o *OSS) Engine() string {
|
||||||
@ -236,7 +241,7 @@ func (o *OSS) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyO
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSS) IsNotFound(err error) bool {
|
func (o *OSS) IsNotFound(err error) bool {
|
||||||
switch e := err.(type) {
|
switch e := errs.Unwrap(err).(type) {
|
||||||
case oss.ServiceError:
|
case oss.ServiceError:
|
||||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||||
case *oss.ServiceError:
|
case *oss.ServiceError:
|
||||||
@ -282,7 +287,6 @@ func (o *OSS) ListUploadedParts(ctx context.Context, uploadID string, name strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||||
publicRead := config.Config.Object.Oss.PublicRead
|
|
||||||
var opts []oss.Option
|
var opts []oss.Option
|
||||||
if opt != nil {
|
if opt != nil {
|
||||||
if opt.Image != nil {
|
if opt.Image != nil {
|
||||||
@ -310,7 +314,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration,
|
|||||||
process += ",format," + format
|
process += ",format," + format
|
||||||
opts = append(opts, oss.Process(process))
|
opts = append(opts, oss.Process(process))
|
||||||
}
|
}
|
||||||
if !publicRead {
|
if !o.publicRead {
|
||||||
if opt.ContentType != "" {
|
if opt.ContentType != "" {
|
||||||
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
opts = append(opts, oss.ResponseContentType(opt.ContentType))
|
||||||
}
|
}
|
||||||
@ -324,7 +328,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration,
|
|||||||
} else if expire < time.Second {
|
} else if expire < time.Second {
|
||||||
expire = time.Second
|
expire = time.Second
|
||||||
}
|
}
|
||||||
if !publicRead {
|
if !o.publicRead {
|
||||||
return o.bucket.SignURL(name, http.MethodGet, int64(expire/time.Second), opts...)
|
return o.bucket.SignURL(name, http.MethodGet, int64(expire/time.Second), opts...)
|
||||||
}
|
}
|
||||||
rawParams, err := oss.GetRawParams(opts)
|
rawParams, err := oss.GetRawParams(opts)
|
||||||
|
@ -36,13 +36,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Mongo struct {
|
type Mongo struct {
|
||||||
db *mongo.Client
|
db *mongo.Client
|
||||||
|
config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMongo Initialize MongoDB connection.
|
// NewMongo Initialize MongoDB connection.
|
||||||
func NewMongo() (*Mongo, error) {
|
func NewMongo(config *config.GlobalConfig) (*Mongo, error) {
|
||||||
specialerror.AddReplace(mongo.ErrNoDocuments, errs.ErrRecordNotFound)
|
specialerror.AddReplace(mongo.ErrNoDocuments, errs.ErrRecordNotFound)
|
||||||
uri := buildMongoURI()
|
uri := buildMongoURI(config)
|
||||||
|
|
||||||
var mongoClient *mongo.Client
|
var mongoClient *mongo.Client
|
||||||
var err error
|
var err error
|
||||||
@ -56,7 +57,7 @@ func NewMongo() (*Mongo, error) {
|
|||||||
if err = mongoClient.Ping(ctx, nil); err != nil {
|
if err = mongoClient.Ping(ctx, nil); err != nil {
|
||||||
return nil, errs.Wrap(err, uri)
|
return nil, errs.Wrap(err, uri)
|
||||||
}
|
}
|
||||||
return &Mongo{db: mongoClient}, nil
|
return &Mongo{db: mongoClient, config: config}, nil
|
||||||
}
|
}
|
||||||
if shouldRetry(err) {
|
if shouldRetry(err) {
|
||||||
time.Sleep(time.Second) // exponential backoff could be implemented here
|
time.Sleep(time.Second) // exponential backoff could be implemented here
|
||||||
@ -66,14 +67,14 @@ func NewMongo() (*Mongo, error) {
|
|||||||
return nil, errs.Wrap(err, uri)
|
return nil, errs.Wrap(err, uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildMongoURI() string {
|
func buildMongoURI(config *config.GlobalConfig) string {
|
||||||
uri := os.Getenv("MONGO_URI")
|
uri := os.Getenv("MONGO_URI")
|
||||||
if uri != "" {
|
if uri != "" {
|
||||||
return uri
|
return uri
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Config.Mongo.Uri != "" {
|
if config.Mongo.Uri != "" {
|
||||||
return config.Config.Mongo.Uri
|
return config.Mongo.Uri
|
||||||
}
|
}
|
||||||
|
|
||||||
username := os.Getenv("MONGO_OPENIM_USERNAME")
|
username := os.Getenv("MONGO_OPENIM_USERNAME")
|
||||||
@ -84,21 +85,21 @@ func buildMongoURI() string {
|
|||||||
maxPoolSize := os.Getenv("MONGO_MAX_POOL_SIZE")
|
maxPoolSize := os.Getenv("MONGO_MAX_POOL_SIZE")
|
||||||
|
|
||||||
if username == "" {
|
if username == "" {
|
||||||
username = config.Config.Mongo.Username
|
username = config.Mongo.Username
|
||||||
}
|
}
|
||||||
if password == "" {
|
if password == "" {
|
||||||
password = config.Config.Mongo.Password
|
password = config.Mongo.Password
|
||||||
}
|
}
|
||||||
if address == "" {
|
if address == "" {
|
||||||
address = strings.Join(config.Config.Mongo.Address, ",")
|
address = strings.Join(config.Mongo.Address, ",")
|
||||||
} else if port != "" {
|
} else if port != "" {
|
||||||
address = fmt.Sprintf("%s:%s", address, port)
|
address = fmt.Sprintf("%s:%s", address, port)
|
||||||
}
|
}
|
||||||
if database == "" {
|
if database == "" {
|
||||||
database = config.Config.Mongo.Database
|
database = config.Mongo.Database
|
||||||
}
|
}
|
||||||
if maxPoolSize == "" {
|
if maxPoolSize == "" {
|
||||||
maxPoolSize = fmt.Sprint(config.Config.Mongo.MaxPoolSize)
|
maxPoolSize = fmt.Sprint(config.Mongo.MaxPoolSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
uriFormat := "mongodb://%s/%s?maxPoolSize=%s"
|
uriFormat := "mongodb://%s/%s?maxPoolSize=%s"
|
||||||
@ -122,8 +123,8 @@ func (m *Mongo) GetClient() *mongo.Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDatabase returns the specific database from MongoDB.
|
// GetDatabase returns the specific database from MongoDB.
|
||||||
func (m *Mongo) GetDatabase() *mongo.Database {
|
func (m *Mongo) GetDatabase(database string) *mongo.Database {
|
||||||
return m.db.Database(config.Config.Mongo.Database)
|
return m.db.Database(database)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMsgIndex creates an index for messages in MongoDB.
|
// CreateMsgIndex creates an index for messages in MongoDB.
|
||||||
@ -133,7 +134,7 @@ func (m *Mongo) CreateMsgIndex() error {
|
|||||||
|
|
||||||
// createMongoIndex creates an index in a MongoDB collection.
|
// createMongoIndex creates an index in a MongoDB collection.
|
||||||
func (m *Mongo) createMongoIndex(collection string, isUnique bool, keys ...string) error {
|
func (m *Mongo) createMongoIndex(collection string, isUnique bool, keys ...string) error {
|
||||||
db := m.GetDatabase().Collection(collection)
|
db := m.GetDatabase(m.config.Mongo.Database).Collection(collection)
|
||||||
opts := options.CreateIndexes().SetMaxTime(10 * time.Second)
|
opts := options.CreateIndexes().SetMaxTime(10 * time.Second)
|
||||||
indexView := db.Indexes()
|
indexView := db.Indexes()
|
||||||
|
|
||||||
|
@ -27,17 +27,17 @@ import (
|
|||||||
|
|
||||||
type ServiceAddresses map[string][]int
|
type ServiceAddresses map[string][]int
|
||||||
|
|
||||||
func getServiceAddresses() ServiceAddresses {
|
func getServiceAddresses(config *config2.GlobalConfig) ServiceAddresses {
|
||||||
return ServiceAddresses{
|
return ServiceAddresses{
|
||||||
config2.Config.RpcRegisterName.OpenImUserName: config2.Config.RpcPort.OpenImUserPort,
|
config.RpcRegisterName.OpenImUserName: config.RpcPort.OpenImUserPort,
|
||||||
config2.Config.RpcRegisterName.OpenImFriendName: config2.Config.RpcPort.OpenImFriendPort,
|
config.RpcRegisterName.OpenImFriendName: config.RpcPort.OpenImFriendPort,
|
||||||
config2.Config.RpcRegisterName.OpenImMsgName: config2.Config.RpcPort.OpenImMessagePort,
|
config.RpcRegisterName.OpenImMsgName: config.RpcPort.OpenImMessagePort,
|
||||||
config2.Config.RpcRegisterName.OpenImMessageGatewayName: config2.Config.LongConnSvr.OpenImMessageGatewayPort,
|
config.RpcRegisterName.OpenImMessageGatewayName: config.LongConnSvr.OpenImMessageGatewayPort,
|
||||||
config2.Config.RpcRegisterName.OpenImGroupName: config2.Config.RpcPort.OpenImGroupPort,
|
config.RpcRegisterName.OpenImGroupName: config.RpcPort.OpenImGroupPort,
|
||||||
config2.Config.RpcRegisterName.OpenImAuthName: config2.Config.RpcPort.OpenImAuthPort,
|
config.RpcRegisterName.OpenImAuthName: config.RpcPort.OpenImAuthPort,
|
||||||
config2.Config.RpcRegisterName.OpenImPushName: config2.Config.RpcPort.OpenImPushPort,
|
config.RpcRegisterName.OpenImPushName: config.RpcPort.OpenImPushPort,
|
||||||
config2.Config.RpcRegisterName.OpenImConversationName: config2.Config.RpcPort.OpenImConversationPort,
|
config.RpcRegisterName.OpenImConversationName: config.RpcPort.OpenImConversationPort,
|
||||||
config2.Config.RpcRegisterName.OpenImThirdName: config2.Config.RpcPort.OpenImThirdPort,
|
config.RpcRegisterName.OpenImThirdName: config.RpcPort.OpenImThirdPort,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +46,7 @@ type ConnDirect struct {
|
|||||||
currentServiceAddress string
|
currentServiceAddress string
|
||||||
conns map[string][]*grpc.ClientConn
|
conns map[string][]*grpc.ClientConn
|
||||||
resolverDirect *ResolverDirect
|
resolverDirect *ResolverDirect
|
||||||
|
config *config2.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConnDirect) GetClientLocalConns() map[string][]*grpc.ClientConn {
|
func (cd *ConnDirect) GetClientLocalConns() map[string][]*grpc.ClientConn {
|
||||||
@ -80,10 +81,11 @@ func (cd *ConnDirect) Close() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConnDirect() (*ConnDirect, error) {
|
func NewConnDirect(config *config2.GlobalConfig) (*ConnDirect, error) {
|
||||||
return &ConnDirect{
|
return &ConnDirect{
|
||||||
conns: make(map[string][]*grpc.ClientConn),
|
conns: make(map[string][]*grpc.ClientConn),
|
||||||
resolverDirect: NewResolverDirect(),
|
resolverDirect: NewResolverDirect(),
|
||||||
|
config: config,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,12 +95,12 @@ func (cd *ConnDirect) GetConns(ctx context.Context,
|
|||||||
if conns, exists := cd.conns[serviceName]; exists {
|
if conns, exists := cd.conns[serviceName]; exists {
|
||||||
return conns, nil
|
return conns, nil
|
||||||
}
|
}
|
||||||
ports := getServiceAddresses()[serviceName]
|
ports := getServiceAddresses(cd.config)[serviceName]
|
||||||
var connections []*grpc.ClientConn
|
var connections []*grpc.ClientConn
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
conn, err := cd.dialServiceWithoutResolver(ctx, fmt.Sprintf(config2.Config.Rpc.ListenIP+":%d", port), append(cd.additionalOpts, opts...)...)
|
conn, err := cd.dialServiceWithoutResolver(ctx, fmt.Sprintf(cd.config.Rpc.ListenIP+":%d", port), append(cd.additionalOpts, opts...)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("connect to port %d failed,serviceName %s, IP %s\n", port, serviceName, config2.Config.Rpc.ListenIP)
|
fmt.Printf("connect to port %d failed,serviceName %s, IP %s\n", port, serviceName, cd.config.Rpc.ListenIP)
|
||||||
}
|
}
|
||||||
connections = append(connections, conn)
|
connections = append(connections, conn)
|
||||||
}
|
}
|
||||||
@ -111,7 +113,7 @@ func (cd *ConnDirect) GetConns(ctx context.Context,
|
|||||||
|
|
||||||
func (cd *ConnDirect) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
func (cd *ConnDirect) GetConn(ctx context.Context, serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) {
|
||||||
// Get service addresses
|
// Get service addresses
|
||||||
addresses := getServiceAddresses()
|
addresses := getServiceAddresses(cd.config)
|
||||||
address, ok := addresses[serviceName]
|
address, ok := addresses[serviceName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errs.Wrap(errors.New("unknown service name"), "serviceName", serviceName)
|
return nil, errs.Wrap(errors.New("unknown service name"), "serviceName", serviceName)
|
||||||
@ -119,9 +121,9 @@ func (cd *ConnDirect) GetConn(ctx context.Context, serviceName string, opts ...g
|
|||||||
var result string
|
var result string
|
||||||
for _, addr := range address {
|
for _, addr := range address {
|
||||||
if result != "" {
|
if result != "" {
|
||||||
result = result + "," + fmt.Sprintf(config2.Config.Rpc.ListenIP+":%d", addr)
|
result = result + "," + fmt.Sprintf(cd.config.Rpc.ListenIP+":%d", addr)
|
||||||
} else {
|
} else {
|
||||||
result = fmt.Sprintf(config2.Config.Rpc.ListenIP+":%d", addr)
|
result = fmt.Sprintf(cd.config.Rpc.ListenIP+":%d", addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Try to dial a new connection
|
// Try to dial a new connection
|
||||||
|
@ -16,6 +16,7 @@ package discoveryregister
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
@ -26,19 +27,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewDiscoveryRegister creates a new service discovery and registry client based on the provided environment type.
|
// NewDiscoveryRegister creates a new service discovery and registry client based on the provided environment type.
|
||||||
func NewDiscoveryRegister(envType string) (discoveryregistry.SvcDiscoveryRegistry, error) {
|
func NewDiscoveryRegister(config *config.GlobalConfig) (discoveryregistry.SvcDiscoveryRegistry, error) {
|
||||||
|
|
||||||
if os.Getenv("ENVS_DISCOVERY") != "" {
|
if os.Getenv("ENVS_DISCOVERY") != "" {
|
||||||
envType = os.Getenv("ENVS_DISCOVERY")
|
config.Envs.Discovery = os.Getenv("ENVS_DISCOVERY")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch envType {
|
switch config.Envs.Discovery {
|
||||||
case "zookeeper":
|
case "zookeeper":
|
||||||
return zookeeper.NewZookeeperDiscoveryRegister()
|
return zookeeper.NewZookeeperDiscoveryRegister(config)
|
||||||
case "k8s":
|
case "k8s":
|
||||||
return kubernetes.NewK8sDiscoveryRegister()
|
return kubernetes.NewK8sDiscoveryRegister(config.RpcRegisterName.OpenImMessageGatewayName)
|
||||||
case "direct":
|
case "direct":
|
||||||
return direct.NewConnDirect()
|
return direct.NewConnDirect(config)
|
||||||
default:
|
default:
|
||||||
return nil, errs.Wrap(errors.New("envType not correct"))
|
return nil, errs.Wrap(errors.New("envType not correct"))
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package discoveryregister
|
package discoveryregister
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -32,20 +33,23 @@ func setupTestEnvironment() {
|
|||||||
|
|
||||||
func TestNewDiscoveryRegister(t *testing.T) {
|
func TestNewDiscoveryRegister(t *testing.T) {
|
||||||
setupTestEnvironment()
|
setupTestEnvironment()
|
||||||
|
conf := config.NewGlobalConfig()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
envType string
|
envType string
|
||||||
|
gatewayName string
|
||||||
expectedError bool
|
expectedError bool
|
||||||
expectedResult bool
|
expectedResult bool
|
||||||
}{
|
}{
|
||||||
{"zookeeper", false, true},
|
{"zookeeper", "MessageGateway", false, true},
|
||||||
{"k8s", false, true}, // Assume that the k8s configuration is also set up correctly
|
{"k8s", "MessageGateway", false, true},
|
||||||
{"direct", false, true},
|
{"direct", "MessageGateway", false, true},
|
||||||
{"invalid", true, false},
|
{"invalid", "MessageGateway", true, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
client, err := NewDiscoveryRegister(test.envType)
|
conf.Envs.Discovery = test.envType
|
||||||
|
conf.RpcRegisterName.OpenImMessageGatewayName = test.gatewayName
|
||||||
|
client, err := NewDiscoveryRegister(conf)
|
||||||
|
|
||||||
if test.expectedError {
|
if test.expectedError {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
@ -22,11 +22,12 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/stathat/consistent"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/stathat/consistent"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// K8sDR represents the Kubernetes service discovery and registration client.
|
// K8sDR represents the Kubernetes service discovery and registration client.
|
||||||
@ -34,11 +35,12 @@ type K8sDR struct {
|
|||||||
options []grpc.DialOption
|
options []grpc.DialOption
|
||||||
rpcRegisterAddr string
|
rpcRegisterAddr string
|
||||||
gatewayHostConsistent *consistent.Consistent
|
gatewayHostConsistent *consistent.Consistent
|
||||||
|
gatewayName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewK8sDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, error) {
|
func NewK8sDiscoveryRegister(gatewayName string) (discoveryregistry.SvcDiscoveryRegistry, error) {
|
||||||
gatewayConsistent := consistent.New()
|
gatewayConsistent := consistent.New()
|
||||||
gatewayHosts := getMsgGatewayHost(context.Background())
|
gatewayHosts := getMsgGatewayHost(context.Background(), gatewayName)
|
||||||
for _, v := range gatewayHosts {
|
for _, v := range gatewayHosts {
|
||||||
gatewayConsistent.Add(v)
|
gatewayConsistent.Add(v)
|
||||||
}
|
}
|
||||||
@ -46,10 +48,10 @@ func NewK8sDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cli *K8sDR) Register(serviceName, host string, port int, opts ...grpc.DialOption) error {
|
func (cli *K8sDR) Register(serviceName, host string, port int, opts ...grpc.DialOption) error {
|
||||||
if serviceName != config.Config.RpcRegisterName.OpenImMessageGatewayName {
|
if serviceName != cli.gatewayName {
|
||||||
cli.rpcRegisterAddr = serviceName
|
cli.rpcRegisterAddr = serviceName
|
||||||
} else {
|
} else {
|
||||||
cli.rpcRegisterAddr = getSelfHost(context.Background())
|
cli.rpcRegisterAddr = getSelfHost(context.Background(), cli.gatewayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -81,15 +83,15 @@ func (cli *K8sDR) GetUserIdHashGatewayHost(ctx context.Context, userId string) (
|
|||||||
}
|
}
|
||||||
return host, err
|
return host, err
|
||||||
}
|
}
|
||||||
func getSelfHost(ctx context.Context) string {
|
func getSelfHost(ctx context.Context, gatewayName string) string {
|
||||||
port := 88
|
port := 88
|
||||||
instance := "openimserver"
|
instance := "openimserver"
|
||||||
selfPodName := os.Getenv("MY_POD_NAME")
|
selfPodName := os.Getenv("MY_POD_NAME")
|
||||||
ns := os.Getenv("MY_POD_NAMESPACE")
|
ns := os.Getenv("MY_POD_NAMESPACE")
|
||||||
statefuleIndex := 0
|
statefuleIndex := 0
|
||||||
gatewayEnds := strings.Split(config.Config.RpcRegisterName.OpenImMessageGatewayName, ":")
|
gatewayEnds := strings.Split(gatewayName, ":")
|
||||||
if len(gatewayEnds) != 2 {
|
if len(gatewayEnds) != 2 {
|
||||||
log.ZError(ctx, "msggateway RpcRegisterName is error:config.Config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
log.ZError(ctx, "msggateway RpcRegisterName is error:config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
||||||
} else {
|
} else {
|
||||||
port, _ = strconv.Atoi(gatewayEnds[1])
|
port, _ = strconv.Atoi(gatewayEnds[1])
|
||||||
}
|
}
|
||||||
@ -102,15 +104,15 @@ func getSelfHost(ctx context.Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// like openimserver-openim-msggateway-0.openimserver-openim-msggateway-headless.openim-lin.svc.cluster.local:88.
|
// like openimserver-openim-msggateway-0.openimserver-openim-msggateway-headless.openim-lin.svc.cluster.local:88.
|
||||||
func getMsgGatewayHost(ctx context.Context) []string {
|
func getMsgGatewayHost(ctx context.Context, gatewayName string) []string {
|
||||||
port := 88
|
port := 88
|
||||||
instance := "openimserver"
|
instance := "openimserver"
|
||||||
selfPodName := os.Getenv("MY_POD_NAME")
|
selfPodName := os.Getenv("MY_POD_NAME")
|
||||||
replicas := os.Getenv("MY_MSGGATEWAY_REPLICACOUNT")
|
replicas := os.Getenv("MY_MSGGATEWAY_REPLICACOUNT")
|
||||||
ns := os.Getenv("MY_POD_NAMESPACE")
|
ns := os.Getenv("MY_POD_NAMESPACE")
|
||||||
gatewayEnds := strings.Split(config.Config.RpcRegisterName.OpenImMessageGatewayName, ":")
|
gatewayEnds := strings.Split(gatewayName, ":")
|
||||||
if len(gatewayEnds) != 2 {
|
if len(gatewayEnds) != 2 {
|
||||||
log.ZError(ctx, "msggateway RpcRegisterName is error:config.Config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
log.ZError(ctx, "msggateway RpcRegisterName is error:config.RpcRegisterName.OpenImMessageGatewayName", errors.New("config error"))
|
||||||
} else {
|
} else {
|
||||||
port, _ = strconv.Atoi(gatewayEnds[1])
|
port, _ = strconv.Atoi(gatewayEnds[1])
|
||||||
}
|
}
|
||||||
@ -131,7 +133,7 @@ func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc
|
|||||||
|
|
||||||
// This conditional checks if the serviceName is not the OpenImMessageGatewayName.
|
// This conditional checks if the serviceName is not the OpenImMessageGatewayName.
|
||||||
// It seems to handle a special case for the OpenImMessageGateway.
|
// It seems to handle a special case for the OpenImMessageGateway.
|
||||||
if serviceName != config.Config.RpcRegisterName.OpenImMessageGatewayName {
|
if serviceName != cli.gatewayName {
|
||||||
// DialContext creates a client connection to the given target (serviceName) using the specified context.
|
// DialContext creates a client connection to the given target (serviceName) using the specified context.
|
||||||
// 'cli.options' are likely default or common options for all connections in this struct.
|
// 'cli.options' are likely default or common options for all connections in this struct.
|
||||||
// 'opts...' allows for additional gRPC dial options to be passed and used.
|
// 'opts...' allows for additional gRPC dial options to be passed and used.
|
||||||
@ -146,7 +148,7 @@ func (cli *K8sDR) GetConns(ctx context.Context, serviceName string, opts ...grpc
|
|||||||
|
|
||||||
// getMsgGatewayHost presumably retrieves hosts for the message gateway service.
|
// getMsgGatewayHost presumably retrieves hosts for the message gateway service.
|
||||||
// The context is passed, likely for cancellation and timeout control.
|
// The context is passed, likely for cancellation and timeout control.
|
||||||
gatewayHosts := getMsgGatewayHost(ctx)
|
gatewayHosts := getMsgGatewayHost(ctx, cli.gatewayName)
|
||||||
|
|
||||||
// Iterating over the retrieved gateway hosts.
|
// Iterating over the retrieved gateway hosts.
|
||||||
for _, host := range gatewayHosts {
|
for _, host := range gatewayHosts {
|
||||||
|
@ -28,11 +28,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewZookeeperDiscoveryRegister creates a new instance of ZookeeperDR for Zookeeper service discovery and registration.
|
// NewZookeeperDiscoveryRegister creates a new instance of ZookeeperDR for Zookeeper service discovery and registration.
|
||||||
func NewZookeeperDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, error) {
|
func NewZookeeperDiscoveryRegister(config *config.GlobalConfig) (discoveryregistry.SvcDiscoveryRegistry, error) {
|
||||||
schema := getEnv("ZOOKEEPER_SCHEMA", config.Config.Zookeeper.Schema)
|
schema := getEnv("ZOOKEEPER_SCHEMA", config.Zookeeper.Schema)
|
||||||
zkAddr := getZkAddrFromEnv(config.Config.Zookeeper.ZkAddr)
|
zkAddr := getZkAddrFromEnv(config.Zookeeper.ZkAddr)
|
||||||
username := getEnv("ZOOKEEPER_USERNAME", config.Config.Zookeeper.Username)
|
username := getEnv("ZOOKEEPER_USERNAME", config.Zookeeper.Username)
|
||||||
password := getEnv("ZOOKEEPER_PASSWORD", config.Config.Zookeeper.Password)
|
password := getEnv("ZOOKEEPER_PASSWORD", config.Zookeeper.Password)
|
||||||
|
|
||||||
zk, err := openkeeper.NewClient(
|
zk, err := openkeeper.NewClient(
|
||||||
zkAddr,
|
zkAddr,
|
||||||
@ -46,10 +46,10 @@ func NewZookeeperDiscoveryRegister() (discoveryregistry.SvcDiscoveryRegistry, er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
uriFormat := "address:%s, username:%s, password:%s, schema:%s."
|
uriFormat := "address:%s, username:%s, password:%s, schema:%s."
|
||||||
errInfo := fmt.Sprintf(uriFormat,
|
errInfo := fmt.Sprintf(uriFormat,
|
||||||
config.Config.Zookeeper.ZkAddr,
|
config.Zookeeper.ZkAddr,
|
||||||
config.Config.Zookeeper.Username,
|
config.Zookeeper.Username,
|
||||||
config.Config.Zookeeper.Password,
|
config.Zookeeper.Password,
|
||||||
config.Config.Zookeeper.Schema)
|
config.Zookeeper.Schema)
|
||||||
return nil, errs.Wrap(err, errInfo)
|
return nil, errs.Wrap(err, errInfo)
|
||||||
}
|
}
|
||||||
return zk, nil
|
return zk, nil
|
||||||
|
@ -17,6 +17,8 @@ package kafka
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
)
|
)
|
||||||
@ -29,22 +31,31 @@ type Consumer struct {
|
|||||||
Consumer sarama.Consumer
|
Consumer sarama.Consumer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKafkaConsumer(addr []string, topic string, kafkaConfig *sarama.Config) (*Consumer, error) {
|
func NewKafkaConsumer(addr []string, topic string, config *config.GlobalConfig) (*Consumer,error) {
|
||||||
p := Consumer{
|
p := Consumer{}
|
||||||
Topic: topic,
|
p.Topic = topic
|
||||||
addr: addr,
|
p.addr = addr
|
||||||
|
consumerConfig := sarama.NewConfig()
|
||||||
|
if config.Kafka.Username != "" && config.Kafka.Password != "" {
|
||||||
|
consumerConfig.Net.SASL.Enable = true
|
||||||
|
consumerConfig.Net.SASL.User = config.Kafka.Username
|
||||||
|
consumerConfig.Net.SASL.Password = config.Kafka.Password
|
||||||
}
|
}
|
||||||
|
var tlsConfig *TLSConfig
|
||||||
if kafkaConfig.Net.SASL.User != "" && kafkaConfig.Net.SASL.Password != "" {
|
if config.Kafka.TLS != nil {
|
||||||
kafkaConfig.Net.SASL.Enable = true
|
tlsConfig = &TLSConfig{
|
||||||
|
CACrt: config.Kafka.TLS.CACrt,
|
||||||
|
ClientCrt: config.Kafka.TLS.ClientCrt,
|
||||||
|
ClientKey: config.Kafka.TLS.ClientKey,
|
||||||
|
ClientKeyPwd: config.Kafka.TLS.ClientKeyPwd,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
err:=SetupTLSConfig(consumerConfig, tlsConfig)
|
||||||
err := SetupTLSConfig(kafkaConfig)
|
if err!=nil{
|
||||||
if err != nil {
|
return nil,err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
consumer, err := sarama.NewConsumer(p.addr, consumerConfig)
|
||||||
consumer, err := sarama.NewConsumer(p.addr, kafkaConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err, "NewKafkaConsumer: creating consumer failed")
|
return nil, errs.Wrap(err, "NewKafkaConsumer: creating consumer failed")
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ package kafka
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MConsumerGroup struct {
|
type MConsumerGroup struct {
|
||||||
@ -35,22 +35,25 @@ type MConsumerGroupConfig struct {
|
|||||||
KafkaVersion sarama.KafkaVersion
|
KafkaVersion sarama.KafkaVersion
|
||||||
OffsetsInitial int64
|
OffsetsInitial int64
|
||||||
IsReturnErr bool
|
IsReturnErr bool
|
||||||
|
UserName string
|
||||||
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMConsumerGroup(consumerConfig *MConsumerGroupConfig, topics, addrs []string, groupID string) (*MConsumerGroup, error) {
|
func NewMConsumerGroup(consumerConfig *MConsumerGroupConfig, topics, addrs []string, groupID string, tlsConfig *TLSConfig) (*MConsumerGroup, error) {
|
||||||
consumerGroupConfig := sarama.NewConfig()
|
consumerGroupConfig := sarama.NewConfig()
|
||||||
consumerGroupConfig.Version = consumerConfig.KafkaVersion
|
consumerGroupConfig.Version = consumerConfig.KafkaVersion
|
||||||
consumerGroupConfig.Consumer.Offsets.Initial = consumerConfig.OffsetsInitial
|
consumerGroupConfig.Consumer.Offsets.Initial = consumerConfig.OffsetsInitial
|
||||||
consumerGroupConfig.Consumer.Return.Errors = consumerConfig.IsReturnErr
|
consumerGroupConfig.Consumer.Return.Errors = consumerConfig.IsReturnErr
|
||||||
if config.Config.Kafka.Username != "" && config.Config.Kafka.Password != "" {
|
if consumerConfig.UserName != "" && consumerConfig.Password != "" {
|
||||||
consumerGroupConfig.Net.SASL.Enable = true
|
consumerGroupConfig.Net.SASL.Enable = true
|
||||||
consumerGroupConfig.Net.SASL.User = config.Config.Kafka.Username
|
consumerGroupConfig.Net.SASL.User = consumerConfig.UserName
|
||||||
consumerGroupConfig.Net.SASL.Password = config.Config.Kafka.Password
|
consumerGroupConfig.Net.SASL.Password = consumerConfig.Password
|
||||||
}
|
}
|
||||||
SetupTLSConfig(consumerGroupConfig)
|
|
||||||
|
SetupTLSConfig(consumerGroupConfig, tlsConfig)
|
||||||
consumerGroup, err := sarama.NewConsumerGroup(addrs, groupID, consumerGroupConfig)
|
consumerGroup, err := sarama.NewConsumerGroup(addrs, groupID, consumerGroupConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err, strings.Join(topics, ","), strings.Join(addrs, ","), groupID, config.Config.Kafka.Username, config.Config.Kafka.Password)
|
return nil, errs.Wrap(err, strings.Join(topics, ","), strings.Join(addrs, ","), groupID, consumerConfig.UserName, consumerConfig.Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &MConsumerGroup{
|
return &MConsumerGroup{
|
||||||
|
@ -22,12 +22,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/OpenIMSDK/protocol/constant"
|
"github.com/OpenIMSDK/protocol/constant"
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
|
||||||
"github.com/OpenIMSDK/tools/log"
|
"github.com/OpenIMSDK/tools/log"
|
||||||
"github.com/OpenIMSDK/tools/mcontext"
|
"github.com/OpenIMSDK/tools/mcontext"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,8 +43,15 @@ type Producer struct {
|
|||||||
producer sarama.SyncProducer
|
producer sarama.SyncProducer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProducerConfig struct {
|
||||||
|
ProducerAck string
|
||||||
|
CompressType string
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
}
|
||||||
|
|
||||||
// NewKafkaProducer initializes a new Kafka producer.
|
// NewKafkaProducer initializes a new Kafka producer.
|
||||||
func NewKafkaProducer(addr []string, topic string) (*Producer, error) {
|
func NewKafkaProducer(addr []string, topic string, producerConfig *ProducerConfig, tlsConfig *TLSConfig) (*Producer, error) {
|
||||||
p := Producer{
|
p := Producer{
|
||||||
addr: addr,
|
addr: addr,
|
||||||
topic: topic,
|
topic: topic,
|
||||||
@ -59,14 +66,14 @@ func NewKafkaProducer(addr []string, topic string) (*Producer, error) {
|
|||||||
p.config.Producer.Partitioner = sarama.NewHashPartitioner
|
p.config.Producer.Partitioner = sarama.NewHashPartitioner
|
||||||
|
|
||||||
// Configure producer acknowledgement level
|
// Configure producer acknowledgement level
|
||||||
configureProducerAck(&p, config.Config.Kafka.ProducerAck)
|
configureProducerAck(&p, producerConfig.ProducerAck)
|
||||||
|
|
||||||
// Configure message compression
|
// Configure message compression
|
||||||
configureCompression(&p, config.Config.Kafka.CompressType)
|
configureCompression(&p, producerConfig.CompressType)
|
||||||
|
|
||||||
// Get Kafka configuration from environment variables or fallback to config file
|
// Get Kafka configuration from environment variables or fallback to config file
|
||||||
kafkaUsername := getEnvOrConfig("KAFKA_USERNAME", config.Config.Kafka.Username)
|
kafkaUsername := getEnvOrConfig("KAFKA_USERNAME", producerConfig.Username)
|
||||||
kafkaPassword := getEnvOrConfig("KAFKA_PASSWORD", config.Config.Kafka.Password)
|
kafkaPassword := getEnvOrConfig("KAFKA_PASSWORD", producerConfig.Password)
|
||||||
kafkaAddr := getKafkaAddrFromEnv(addr) // Updated to use the new function
|
kafkaAddr := getKafkaAddrFromEnv(addr) // Updated to use the new function
|
||||||
|
|
||||||
// Configure SASL authentication if credentials are provided
|
// Configure SASL authentication if credentials are provided
|
||||||
@ -80,7 +87,7 @@ func NewKafkaProducer(addr []string, topic string) (*Producer, error) {
|
|||||||
p.addr = kafkaAddr
|
p.addr = kafkaAddr
|
||||||
|
|
||||||
// Set up TLS configuration (if required)
|
// Set up TLS configuration (if required)
|
||||||
SetupTLSConfig(p.config)
|
SetupTLSConfig(p.config, tlsConfig)
|
||||||
|
|
||||||
// Create the producer with retries
|
// Create the producer with retries
|
||||||
var err error
|
var err error
|
||||||
|
@ -20,19 +20,27 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/IBM/sarama"
|
"github.com/IBM/sarama"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/tls"
|
"github.com/openimsdk/open-im-server/v3/pkg/common/tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TLSConfig struct {
|
||||||
|
CACrt string
|
||||||
|
ClientCrt string
|
||||||
|
ClientKey string
|
||||||
|
ClientKeyPwd string
|
||||||
|
InsecureSkipVerify bool
|
||||||
|
}
|
||||||
|
|
||||||
// SetupTLSConfig set up the TLS config from config file.
|
// SetupTLSConfig set up the TLS config from config file.
|
||||||
func SetupTLSConfig(cfg *sarama.Config) error {
|
func SetupTLSConfig(cfg *sarama.Config, tlsConfig *TLSConfig) error {
|
||||||
if config.Config.Kafka.TLS != nil {
|
if tlsConfig != nil {
|
||||||
cfg.Net.TLS.Enable = true
|
cfg.Net.TLS.Enable = true
|
||||||
tlsConfig, err := tls.NewTLSConfig(
|
tlsConfig, err := tls.NewTLSConfig(
|
||||||
config.Config.Kafka.TLS.ClientCrt,
|
tlsConfig.ClientCrt,
|
||||||
config.Config.Kafka.TLS.ClientKey,
|
tlsConfig.ClientKey,
|
||||||
config.Config.Kafka.TLS.CACrt,
|
tlsConfig.CACrt,
|
||||||
[]byte(config.Config.Kafka.TLS.ClientKeyPwd),
|
[]byte(tlsConfig.ClientKeyPwd),
|
||||||
|
tlsConfig.InsecureSkipVerify,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -31,17 +31,17 @@ func NewGrpcPromObj(cusMetrics []prometheus.Collector) (*prometheus.Registry, *g
|
|||||||
return reg, grpcMetrics, nil
|
return reg, grpcMetrics, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGrpcCusMetrics(registerName string) []prometheus.Collector {
|
func GetGrpcCusMetrics(registerName string, config *config2.GlobalConfig) []prometheus.Collector {
|
||||||
switch registerName {
|
switch registerName {
|
||||||
case config2.Config.RpcRegisterName.OpenImMessageGatewayName:
|
case config.RpcRegisterName.OpenImMessageGatewayName:
|
||||||
return []prometheus.Collector{OnlineUserGauge}
|
return []prometheus.Collector{OnlineUserGauge}
|
||||||
case config2.Config.RpcRegisterName.OpenImMsgName:
|
case config.RpcRegisterName.OpenImMsgName:
|
||||||
return []prometheus.Collector{SingleChatMsgProcessSuccessCounter, SingleChatMsgProcessFailedCounter, GroupChatMsgProcessSuccessCounter, GroupChatMsgProcessFailedCounter}
|
return []prometheus.Collector{SingleChatMsgProcessSuccessCounter, SingleChatMsgProcessFailedCounter, GroupChatMsgProcessSuccessCounter, GroupChatMsgProcessFailedCounter}
|
||||||
case "Transfer":
|
case "Transfer":
|
||||||
return []prometheus.Collector{MsgInsertRedisSuccessCounter, MsgInsertRedisFailedCounter, MsgInsertMongoSuccessCounter, MsgInsertMongoFailedCounter, SeqSetFailedCounter}
|
return []prometheus.Collector{MsgInsertRedisSuccessCounter, MsgInsertRedisFailedCounter, MsgInsertMongoSuccessCounter, MsgInsertMongoFailedCounter, SeqSetFailedCounter}
|
||||||
case config2.Config.RpcRegisterName.OpenImPushName:
|
case config.RpcRegisterName.OpenImPushName:
|
||||||
return []prometheus.Collector{MsgOfflinePushFailedCounter}
|
return []prometheus.Collector{MsgOfflinePushFailedCounter}
|
||||||
case config2.Config.RpcRegisterName.OpenImAuthName:
|
case config.RpcRegisterName.OpenImAuthName:
|
||||||
return []prometheus.Collector{UserLoginCounter}
|
return []prometheus.Collector{UserLoginCounter}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
|
@ -58,17 +58,20 @@ func TestNewGrpcPromObj(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetGrpcCusMetrics(t *testing.T) {
|
func TestGetGrpcCusMetrics(t *testing.T) {
|
||||||
|
conf := config2.NewGlobalConfig()
|
||||||
|
|
||||||
|
config2.InitConfig(conf, "../../config")
|
||||||
// Test various cases based on the switch statement in the GetGrpcCusMetrics function.
|
// Test various cases based on the switch statement in the GetGrpcCusMetrics function.
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
expected int // The expected number of metrics for each case.
|
expected int // The expected number of metrics for each case.
|
||||||
}{
|
}{
|
||||||
{config2.Config.RpcRegisterName.OpenImMessageGatewayName, 1},
|
{conf.RpcRegisterName.OpenImMessageGatewayName, 1},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
metrics := GetGrpcCusMetrics(tc.name)
|
metrics := GetGrpcCusMetrics(tc.name, conf)
|
||||||
assert.Len(t, metrics, tc.expected)
|
assert.Len(t, metrics, tc.expected)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -27,19 +28,25 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/discoveryregistry"
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/OpenIMSDK/tools/mw"
|
|
||||||
"github.com/OpenIMSDK/tools/network"
|
|
||||||
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
|
||||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
|
||||||
|
config2 "github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||||
|
|
||||||
|
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
|
kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister"
|
||||||
|
|
||||||
|
"github.com/OpenIMSDK/tools/discoveryregistry"
|
||||||
|
"github.com/OpenIMSDK/tools/mw"
|
||||||
|
"github.com/OpenIMSDK/tools/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start rpc server.
|
// Start rpc server.
|
||||||
@ -47,37 +54,38 @@ func Start(
|
|||||||
rpcPort int,
|
rpcPort int,
|
||||||
rpcRegisterName string,
|
rpcRegisterName string,
|
||||||
prometheusPort int,
|
prometheusPort int,
|
||||||
rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
config *config2.GlobalConfig,
|
||||||
|
rpcFn func(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error,
|
||||||
options ...grpc.ServerOption,
|
options ...grpc.ServerOption,
|
||||||
) error {
|
) error {
|
||||||
fmt.Printf("start %s server, port: %d, prometheusPort: %d, OpenIM version: %s\n",
|
fmt.Printf("start %s server, port: %d, prometheusPort: %d, OpenIM version: %s\n",
|
||||||
rpcRegisterName, rpcPort, prometheusPort, config.Version)
|
rpcRegisterName, rpcPort, prometheusPort, config2.Version)
|
||||||
rpcTcpAddr := net.JoinHostPort(network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort))
|
rpcTcpAddr := net.JoinHostPort(network.GetListenIP(config.Rpc.ListenIP), strconv.Itoa(rpcPort))
|
||||||
listener, err := net.Listen(
|
listener, err := net.Listen(
|
||||||
"tcp",
|
"tcp",
|
||||||
rpcTcpAddr,
|
rpcTcpAddr,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err, "rpc start err", rpcTcpAddr)
|
return errs.Wrap(err, "listen err", rpcTcpAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
client, err := kdisc.NewDiscoveryRegister(config.Config.Envs.Discovery)
|
client, err := kdisc.NewDiscoveryRegister(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin")))
|
||||||
registerIP, err := network.GetRpcRegisterIP(config.Config.Rpc.RegisterIP)
|
registerIP, err := network.GetRpcRegisterIP(config.Rpc.RegisterIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errs.Wrap(err)
|
return errs.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var reg *prometheus.Registry
|
var reg *prometheus.Registry
|
||||||
var metric *grpcprometheus.ServerMetrics
|
var metric *grpcprometheus.ServerMetrics
|
||||||
if config.Config.Prometheus.Enable {
|
if config.Prometheus.Enable {
|
||||||
cusMetrics := prommetrics.GetGrpcCusMetrics(rpcRegisterName)
|
cusMetrics := prommetrics.GetGrpcCusMetrics(rpcRegisterName, config)
|
||||||
reg, metric, _ = prommetrics.NewGrpcPromObj(cusMetrics)
|
reg, metric, _ = prommetrics.NewGrpcPromObj(cusMetrics)
|
||||||
options = append(options, mw.GrpcServer(), grpc.StreamInterceptor(metric.StreamServerInterceptor()),
|
options = append(options, mw.GrpcServer(), grpc.StreamInterceptor(metric.StreamServerInterceptor()),
|
||||||
grpc.UnaryInterceptor(metric.UnaryServerInterceptor()))
|
grpc.UnaryInterceptor(metric.UnaryServerInterceptor()))
|
||||||
@ -91,7 +99,7 @@ func Start(
|
|||||||
once.Do(srv.GracefulStop)
|
once.Do(srv.GracefulStop)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = rpcFn(client, srv)
|
err = rpcFn(config, client, srv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -111,7 +119,7 @@ func Start(
|
|||||||
httpServer *http.Server
|
httpServer *http.Server
|
||||||
)
|
)
|
||||||
go func() {
|
go func() {
|
||||||
if config.Config.Prometheus.Enable && prometheusPort != 0 {
|
if config.Prometheus.Enable && prometheusPort != 0 {
|
||||||
metric.InitializeMetrics(srv)
|
metric.InitializeMetrics(srv)
|
||||||
// Create a HTTP server for prometheus.
|
// Create a HTTP server for prometheus.
|
||||||
httpServer = &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: fmt.Sprintf("0.0.0.0:%d", prometheusPort)}
|
httpServer = &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: fmt.Sprintf("0.0.0.0:%d", prometheusPort)}
|
||||||
|
@ -16,6 +16,7 @@ package startrpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -25,7 +26,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// mockRpcFn is a mock gRPC function for testing.
|
// mockRpcFn is a mock gRPC function for testing.
|
||||||
func mockRpcFn(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
func mockRpcFn(config *config.GlobalConfig, client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
|
||||||
// Implement a mock gRPC service registration logic if needed
|
// Implement a mock gRPC service registration logic if needed
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -40,7 +41,8 @@ func TestStart(t *testing.T) {
|
|||||||
doneChan := make(chan error, 1)
|
doneChan := make(chan error, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err := Start(testRpcPort, testRpcRegisterName, testPrometheusPort, mockRpcFn)
|
err := Start(testRpcPort, testRpcRegisterName, testPrometheusPort,
|
||||||
|
config.NewGlobalConfig(), mockRpcFn)
|
||||||
doneChan <- err
|
doneChan <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
8
pkg/common/tls/tls.go
Normal file → Executable file
8
pkg/common/tls/tls.go
Normal file → Executable file
@ -22,7 +22,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/OpenIMSDK/tools/errs"
|
"github.com/OpenIMSDK/tools/errs"
|
||||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// decryptPEM decrypts a PEM block using a password.
|
// decryptPEM decrypts a PEM block using a password.
|
||||||
@ -50,15 +49,14 @@ func readEncryptablePEMBlock(path string, pwd []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewTLSConfig setup the TLS config from general config file.
|
// NewTLSConfig setup the TLS config from general config file.
|
||||||
func NewTLSConfig(clientCertFile, clientKeyFile, caCertFile string, keyPwd []byte) (*tls.Config, error) {
|
func NewTLSConfig(clientCertFile, clientKeyFile, caCertFile string, keyPwd []byte, insecureSkipVerify bool) (*tls.Config,error) {
|
||||||
var tlsConfig tls.Config
|
tlsConfig := tls.Config{}
|
||||||
|
|
||||||
if clientCertFile != "" && clientKeyFile != "" {
|
if clientCertFile != "" && clientKeyFile != "" {
|
||||||
certPEMBlock, err := os.ReadFile(clientCertFile)
|
certPEMBlock, err := os.ReadFile(clientCertFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(err, "NewTLSConfig: failed to read client cert file")
|
return nil, errs.Wrap(err, "NewTLSConfig: failed to read client cert file")
|
||||||
}
|
}
|
||||||
|
|
||||||
keyPEMBlock, err := readEncryptablePEMBlock(clientKeyFile, keyPwd)
|
keyPEMBlock, err := readEncryptablePEMBlock(clientKeyFile, keyPwd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -84,7 +82,7 @@ func NewTLSConfig(clientCertFile, clientKeyFile, caCertFile string, keyPwd []byt
|
|||||||
tlsConfig.RootCAs = caCertPool
|
tlsConfig.RootCAs = caCertPool
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfig.InsecureSkipVerify = config.Config.Kafka.TLS.InsecureSkipVerify
|
tlsConfig.InsecureSkipVerify = insecureSkipVerify
|
||||||
|
|
||||||
return &tlsConfig, nil
|
return &tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,18 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry) *Auth {
|
func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) *Auth {
|
||||||
conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImAuthName)
|
conn, err := discov.GetConn(context.Background(), config.RpcRegisterName.OpenImAuthName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
client := auth.NewAuthClient(conn)
|
client := auth.NewAuthClient(conn)
|
||||||
return &Auth{discov: discov, conn: conn, Client: client}
|
return &Auth{discov: discov, conn: conn, Client: client, Config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Auth struct {
|
type Auth struct {
|
||||||
conn grpc.ClientConnInterface
|
conn grpc.ClientConnInterface
|
||||||
Client auth.AuthClient
|
Client auth.AuthClient
|
||||||
discov discoveryregistry.SvcDiscoveryRegistry
|
discov discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
Config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,22 @@ type Conversation struct {
|
|||||||
Client pbconversation.ConversationClient
|
Client pbconversation.ConversationClient
|
||||||
conn grpc.ClientConnInterface
|
conn grpc.ClientConnInterface
|
||||||
discov discoveryregistry.SvcDiscoveryRegistry
|
discov discoveryregistry.SvcDiscoveryRegistry
|
||||||
|
Config *config.GlobalConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConversation(discov discoveryregistry.SvcDiscoveryRegistry) *Conversation {
|
func NewConversation(discov discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) *Conversation {
|
||||||
conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImConversationName)
|
conn, err := discov.GetConn(context.Background(), config.RpcRegisterName.OpenImConversationName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.ExitWithError(err)
|
util.ExitWithError(err)
|
||||||
}
|
}
|
||||||
client := pbconversation.NewConversationClient(conn)
|
client := pbconversation.NewConversationClient(conn)
|
||||||
return &Conversation{discov: discov, conn: conn, Client: client}
|
return &Conversation{discov: discov, conn: conn, Client: client, Config: config}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConversationRpcClient Conversation
|
type ConversationRpcClient Conversation
|
||||||
|
|
||||||
func NewConversationRpcClient(discov discoveryregistry.SvcDiscoveryRegistry) ConversationRpcClient {
|
func NewConversationRpcClient(discov discoveryregistry.SvcDiscoveryRegistry, config *config.GlobalConfig) ConversationRpcClient {
|
||||||
return ConversationRpcClient(*NewConversation(discov))
|
return ConversationRpcClient(*NewConversation(discov, config))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Context, userID, conversationID string) (int32, error) {
|
func (c *ConversationRpcClient) GetSingleConversationRecvMsgOpt(ctx context.Context, userID, conversationID string) (int32, error) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user