diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d8b13d3a4..dc003ca20 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,16 +6,6 @@ "build": { "dockerfile": "Dockerfile" }, // Replace with uncommented line below to build your own local copy of the image // "dockerFile": "../docker/Dockerfile-dev", - "containerEnv": { - // Uncomment to overwrite devcontainer .kube/config and .minikube certs with the localhost versions - // each time the devcontainer starts, if the respective .kube-localhost/config and .minikube-localhost - // folders respectively are bind mounted to the devcontainer. - // "SYNC_LOCALHOST_KUBECONFIG": "true" - - // Uncomment to disable docker-in-docker and automatically proxy default /var/run/docker.sock to - // the localhost bind-mount /var/run/docker-host.sock. - // "BIND_LOCALHOST_DOCKER": "true" - }, "remoteEnv": { "GO111MODULE": "on", "GOPROXY": "https://goproxy.cn", diff --git a/assets/colors.md b/assets/colors.md new file mode 100644 index 000000000..cf8777719 --- /dev/null +++ b/assets/colors.md @@ -0,0 +1,11 @@ +# Official Colors + +The openim logo has an official blue color. When reproducing the logo, please use the official color, when possible. + +## Pantone + +When possible, the Pantone color is preferred for print material. The official Pantone color is *285C*. + +## RGB + +When used digitally, the official RGB color code is *#326CE5*. diff --git a/deployments/templates/openim.yaml b/deployments/templates/openim.yaml index ed3fb261a..978d9dfb9 100644 --- a/deployments/templates/openim.yaml +++ b/deployments/templates/openim.yaml @@ -315,7 +315,7 @@ iosPush: # Timeout in seconds # Whether to continue execution if callback fails callback: - url: "" + url: "http://127.0.0.1:10008/callbackExample" beforeSendSingleMsg: enable: ${CALLBACK_ENABLE} timeout: ${CALLBACK_TIMEOUT} @@ -329,7 +329,7 @@ callback: timeout: ${CALLBACK_TIMEOUT} failedContinue: ${CALLBACK_FAILED_CONTINUE} afterSendSingleMsg: - enable: ${CALLBACK_ENABLE} + enable: true timeout: ${CALLBACK_TIMEOUT} failedContinue: ${CALLBACK_FAILED_CONTINUE} beforeSendGroupMsg: diff --git a/docker-compose.yml b/docker-compose.yml index 24735abe9..6d0f3c25a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -123,7 +123,7 @@ services: ipv4_address: ${OPENIM_WEB_NETWORK_ADDRESS:-172.28.0.7} ### TODO: Uncomment, or deploy using openim docker: https://github.com/openimsdk/openim-docker - # Uncomment and configure the following services as needed +### Uncomment and configure the following services as needed # openim-server: # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-server:${SERVER_IMAGE_VERSION:-main} @@ -172,6 +172,23 @@ services: # server: # ipv4_address: ${OPENIM_SERVER_NETWORK_ADDRESS:-172.28.0.8} +### TODO: mysql is required to deploy the openim-chat component + # mysql: + # image: mysql:${MYSQL_IMAGE_VERSION:-5.7} + # platform: linux/amd64 + # ports: + # - "${MYSQL_PORT:-13306}:3306" + # container_name: mysql + # volumes: + # - "${DATA_DIR:-./}/components/mysql/data:/var/lib/mysql" + # - "/etc/localtime:/etc/localtime" + # environment: + # MYSQL_ROOT_PASSWORD: "${MYSQL_PASSWORD:-openIM123}" + # restart: always + # networks: + # server: + # ipv4_address: ${MYSQL_NETWORK_ADDRESS:-172.28.0.15} + # openim-chat: # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-chat:${CHAT_IMAGE_VERSION:-main} # container_name: openim-chat @@ -199,6 +216,11 @@ services: # - "${DATA_DIR:-./}/components/openim-chat/config:/openim/openim-chat/config" # restart: always # # user: root:root + # depends_on: + # - mysql + # - kafka + # - redis + # - zookeeper # logging: # driver: json-file # options: diff --git a/docs/contrib/mac-developer-deployment-guide.md b/docs/contrib/mac-developer-deployment-guide.md index 40ef4b8be..69e4e7503 100644 --- a/docs/contrib/mac-developer-deployment-guide.md +++ b/docs/contrib/mac-developer-deployment-guide.md @@ -47,25 +47,58 @@ Homebrew is an essential package manager for macOS. Install it using: ### Forking and Cloning the Repository -1. Fork the OpenIM repository on GitHub to your account. -2. Clone your fork to your local machine: +To optimize and add logic to your instructions, particularly regarding deploying on a Mac, you can modify them as follows: + +1. **Fork the OpenIM Repository**: Fork the OpenIM repository on GitHub to your account. + +2. **Clone Your Fork to Your Local Machine**: + Open your terminal and execute the following commands: ```sh + # Clone the repository git clone https://github.com//open-im-server.git - # The Docker bridging network mode for Mac is slightly different and needs to be set: + + # Set Docker bridging network mode for Mac export DOCKER_BRIDGE_SUBNET=127.0.0.0/16 + # Set OpenIM IP export OPENIM_IP= - # Init Config + + # Initialize configuration make init - # Start Components + # Start components using Docker docker compose up -d # Start OpenIM Server make start ``` +3. **Additional Steps for Mac Deployment**: + If you are deploying on a Mac and wish to use the chat feature, you need to modify the `docker-compose` file. Specifically, you'll need to uncomment the sections related to `openim-chat` and `mysql`. + + Here's how to do it: + + - Open the `docker-compose.yml` file in a text editor. + - Find the sections for `openim-chat` and `mysql`. + - Remove the comment marks (`#`) at the beginning of the lines in these sections to enable them. + - Save the file after making these changes. + +4. **Update and Restart Services**: + After modifying the `docker-compose` file, you need to update and restart the services to apply these changes. Run the following command in your terminal: + + ```sh + # Update and restart services + docker compose up -d + + # Check openim-chat start + docker compose logs openim-chat + ``` + + This command will re-read the `docker-compose.yml` file, apply the new configuration, and restart the necessary containers. + +Remember, replacing `` and `` with your actual GitHub username and desired IP address for OpenIM is crucial. These steps should streamline the setup process, particularly for Mac users wishing to use the chat feature. + ### Setting Up the Devcontainer `Devcontainers` provide a Docker-based isolated development environment. diff --git a/go.mod b/go.mod index bf54752c9..a35e422bd 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v2.2.9+incompatible github.com/go-redis/redis v6.15.9+incompatible github.com/redis/go-redis/v9 v9.2.1 + github.com/spf13/pflag v1.0.5 github.com/stathat/consistent v1.0.0 github.com/tencentyun/cos-go-sdk-v5 v0.7.45 go.uber.org/automaxprocs v1.5.3 @@ -118,7 +119,6 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/xid v1.5.0 // indirect github.com/sergi/go-diff v1.0.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/src-d/gcfg v1.4.0 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect @@ -133,8 +133,8 @@ require ( golang.org/x/arch v0.3.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -155,10 +155,8 @@ require ( github.com/spf13/cobra v1.7.0 github.com/ugorji/go/codec v1.2.11 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.17.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) replace github.com/openimsdk/localcache => ./pkg/localcache - -replace github.com/OpenIMSDK/protocol v0.0.47 => github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94 diff --git a/go.sum b/go.sum index 7c318e02a..61d521be1 100644 --- a/go.sum +++ b/go.sum @@ -373,8 +373,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= @@ -440,12 +440,12 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -453,8 +453,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go index 7e8129105..01d92b92a 100644 --- a/internal/msggateway/n_ws_server.go +++ b/internal/msggateway/n_ws_server.go @@ -19,7 +19,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/OpenIMSDK/tools/apiresp" "net/http" "os" "os/signal" @@ -29,6 +28,8 @@ import ( "syscall" "time" + "github.com/OpenIMSDK/tools/apiresp" + "github.com/go-playground/validator/v10" "github.com/redis/go-redis/v9" "golang.org/x/sync/errgroup" diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index d0d59547c..40803089c 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -17,9 +17,10 @@ package conversation import ( "context" "errors" - "github.com/OpenIMSDK/protocol/sdkws" "sort" + "github.com/OpenIMSDK/protocol/sdkws" + "github.com/OpenIMSDK/tools/tx" "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" diff --git a/internal/rpc/msg/as_read.go b/internal/rpc/msg/as_read.go index a2bcb84bf..5a4f8b5f3 100644 --- a/internal/rpc/msg/as_read.go +++ b/internal/rpc/msg/as_read.go @@ -18,6 +18,7 @@ import ( "context" utils2 "github.com/OpenIMSDK/tools/utils" + cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" "github.com/redis/go-redis/v9" @@ -124,6 +125,17 @@ func (m *msgServer) MarkMsgsAsRead( return } } + + req_callback := &cbapi.CallbackSingleMsgReadReq{ + ConversationID: conversation.ConversationID, + UserID: req.UserID, + Seqs: req.Seqs, + ContentType: conversation.ConversationType, + } + if err = CallbackSingleMsgRead(ctx, req_callback); err != nil { + return nil, err + } + if err = m.sendMarkAsReadNotification(ctx, req.ConversationID, conversation.ConversationType, req.UserID, m.conversationAndGetRecvID(conversation, req.UserID), req.Seqs, hasReadSeq); err != nil { return diff --git a/internal/rpc/msg/seq.go b/internal/rpc/msg/seq.go index c12f258b7..dfc2ad0b1 100644 --- a/internal/rpc/msg/seq.go +++ b/internal/rpc/msg/seq.go @@ -16,6 +16,7 @@ package msg import ( "context" + pbmsg "github.com/OpenIMSDK/protocol/msg" ) diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index 2c230f258..3b501d4ad 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -19,12 +19,14 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" - "github.com/google/uuid" - "github.com/openimsdk/open-im-server/v3/pkg/authverify" "path" "strconv" "time" + "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/protocol/third" diff --git a/internal/rpc/user/callback.go b/internal/rpc/user/callback.go index 092a66a07..5276946a4 100644 --- a/internal/rpc/user/callback.go +++ b/internal/rpc/user/callback.go @@ -16,6 +16,7 @@ package user import ( "context" + pbuser "github.com/OpenIMSDK/protocol/user" "github.com/OpenIMSDK/tools/utils" diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index f647d6686..e09c3299a 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -17,12 +17,14 @@ package user import ( "context" "errors" - "github.com/OpenIMSDK/tools/pagination" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "math/rand" "strings" "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" @@ -229,14 +231,14 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR } func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) { - if req.UserID == "" && req.UserName == "" { + if req.UserID == "" && req.NickName == "" { total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.Pagination) if err != nil { return nil, err } return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err } else { - total, users, err := s.PageFindUserWithKeyword(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.UserID, req.UserName, req.Pagination) + total, users, err := s.PageFindUserWithKeyword(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.UserID, req.NickName, req.Pagination) if err != nil { return nil, err } diff --git a/pkg/callbackstruct/message.go b/pkg/callbackstruct/message.go index ae36d7139..2864e28b1 100644 --- a/pkg/callbackstruct/message.go +++ b/pkg/callbackstruct/message.go @@ -94,9 +94,10 @@ type CallbackGroupMsgReadResp struct { type CallbackSingleMsgReadReq struct { CallbackCommand `json:"callbackCommand"` - SendID string `json:"sendID"` - ReceiveID string `json:"receiveID"` - ContentType int64 `json:"contentType"` + ConversationID string `json:"conversationID"` + UserID string `json:"userID"` + Seqs []int64 `json:"Seqs"` + ContentType int32 `json:"contentType"` } type CallbackSingleMsgReadResp struct { diff --git a/pkg/common/config/parse.go b/pkg/common/config/parse.go index 1410a5a4a..64719d6a1 100644 --- a/pkg/common/config/parse.go +++ b/pkg/common/config/parse.go @@ -24,6 +24,7 @@ import ( "gopkg.in/yaml.v3" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" + "github.com/openimsdk/open-im-server/v3/pkg/util/genutil" ) //go:embed version @@ -37,19 +38,30 @@ const ( // return absolude path join ../config/, this is k8s container config path. func GetDefaultConfigPath() string { - b, err := filepath.Abs(os.Args[0]) + executablePath, err := os.Executable() if err != nil { - fmt.Println("filepath.Abs error,err=", err) + fmt.Println("GetDefaultConfigPath error:", err.Error()) return "" } - return filepath.Join(filepath.Dir(b), "../config/") + + configPath, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../config/")) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err) + os.Exit(1) + } + return configPath } // getProjectRoot returns the absolute path of the project root directory. func GetProjectRoot() string { - b, _ := filepath.Abs(os.Args[0]) + executablePath, _ := os.Executable() - return filepath.Join(filepath.Dir(b), "../../../../..") + projectRoot, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../../../../..")) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err) + os.Exit(1) + } + return projectRoot } func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options { diff --git a/pkg/common/convert/friend.go b/pkg/common/convert/friend.go index 62ce6f95b..27bd595ad 100644 --- a/pkg/common/convert/friend.go +++ b/pkg/common/convert/friend.go @@ -17,6 +17,7 @@ package convert import ( "context" "fmt" + "github.com/OpenIMSDK/protocol/sdkws" "github.com/OpenIMSDK/tools/utils" diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index b1cace955..78ac5a701 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -51,7 +51,7 @@ type UserDatabase interface { // FindUser PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) //FindUser with keyword - PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, nickName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // Page If not found, no error is returned Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // IsExist true as long as one exists @@ -190,8 +190,15 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { return u.userDB.PageFindUser(ctx, level1, level2, pagination) } -func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, userName, pagination) + +func (u *userDatabase) PageFindUserWithKeyword( + ctx context.Context, + level1 int64, + level2 int64, + userID, nickName string, + pagination pagination.Pagination, +) (count int64, users []*relation.UserModel, err error) { + return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, nickName, pagination) } // IsExist Does userIDs exist? As long as there is one, it will be true. diff --git a/pkg/common/db/mgo/friend.go b/pkg/common/db/mgo/friend.go index b4172d0fb..851db6157 100644 --- a/pkg/common/db/mgo/friend.go +++ b/pkg/common/db/mgo/friend.go @@ -16,6 +16,7 @@ package mgo import ( "context" + "github.com/OpenIMSDK/tools/mgoutil" "github.com/OpenIMSDK/tools/pagination" "go.mongodb.org/mongo-driver/mongo/options" diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go index 3ab71b209..34a25ed08 100644 --- a/pkg/common/db/mgo/user.go +++ b/pkg/common/db/mgo/user.go @@ -16,10 +16,11 @@ package mgo import ( "context" + "time" + "github.com/OpenIMSDK/protocol/user" "github.com/OpenIMSDK/tools/errs" "go.mongodb.org/mongo-driver/bson/primitive" - "time" "github.com/OpenIMSDK/tools/mgoutil" "github.com/OpenIMSDK/tools/pagination" @@ -89,7 +90,15 @@ func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) } -func (u *UserMgo) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + +func (u *UserMgo) PageFindUserWithKeyword( + ctx context.Context, + level1 int64, + level2 int64, + userID string, + nickName string, + pagination pagination.Pagination, +) (count int64, users []*relation.UserModel, err error) { // Initialize the base query with level conditions query := bson.M{ "$and": []bson.M{ @@ -98,16 +107,16 @@ func (u *UserMgo) PageFindUserWithKeyword(ctx context.Context, level1 int64, lev } // Add userID and userName conditions to the query if they are provided - if userID != "" || userName != "" { + if userID != "" || nickName != "" { userConditions := []bson.M{} if userID != "" { // Use regex for userID regexPattern := primitive.Regex{Pattern: userID, Options: "i"} // 'i' for case-insensitive matching userConditions = append(userConditions, bson.M{"user_id": regexPattern}) } - if userName != "" { + if nickName != "" { // Use regex for userName - regexPattern := primitive.Regex{Pattern: userName, Options: "i"} // 'i' for case-insensitive matching + regexPattern := primitive.Regex{Pattern: nickName, Options: "i"} // 'i' for case-insensitive matching userConditions = append(userConditions, bson.M{"nickname": regexPattern}) } query["$and"] = append(query["$and"].([]bson.M), bson.M{"$or": userConditions}) diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 8d40a8f67..dbb2ff464 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -16,9 +16,10 @@ package relation import ( "context" - "github.com/OpenIMSDK/protocol/user" "time" + "github.com/OpenIMSDK/protocol/user" + "github.com/OpenIMSDK/tools/pagination" ) @@ -57,7 +58,7 @@ type UserModelInterface interface { TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) - PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*UserModel, err error) Exist(ctx context.Context, userID string) (exist bool, err error) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) diff --git a/pkg/common/discoveryregister/kubernetes/kubernetes.go b/pkg/common/discoveryregister/kubernetes/kubernetes.go index c10518056..06c58d961 100644 --- a/pkg/common/discoveryregister/kubernetes/kubernetes.go +++ b/pkg/common/discoveryregister/kubernetes/kubernetes.go @@ -18,15 +18,17 @@ import ( "context" "errors" "fmt" - "github.com/stathat/consistent" "os" "strconv" "strings" + "github.com/stathat/consistent" + "google.golang.org/grpc" "github.com/OpenIMSDK/tools/discoveryregistry" "github.com/OpenIMSDK/tools/log" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" ) diff --git a/pkg/rpcclient/msg.go b/pkg/rpcclient/msg.go index abad0075a..56167d7f4 100644 --- a/pkg/rpcclient/msg.go +++ b/pkg/rpcclient/msg.go @@ -17,6 +17,7 @@ package rpcclient import ( "context" "encoding/json" + "google.golang.org/grpc" "google.golang.org/protobuf/proto" diff --git a/pkg/util/flag/flag.go b/pkg/util/flag/flag.go new file mode 100644 index 000000000..7bbacf444 --- /dev/null +++ b/pkg/util/flag/flag.go @@ -0,0 +1,40 @@ +package flag + +import ( + goFlag "flag" + "log" + "strings" + + "github.com/spf13/pflag" +) + +// WordSepNormalizeFunc changes all flags that contain "_" separators. +func WordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { + if strings.Contains(name, "_") { + return pflag.NormalizedName(strings.ReplaceAll(name, "_", "-")) + } + return pflag.NormalizedName(name) +} + +// WarnWordSepNormalizeFunc changes and warns for flags that contain "_" separators. +func WarnWordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { + if strings.Contains(name, "_") { + normalizedName := strings.ReplaceAll(name, "_", "-") + log.Printf("WARNING: flag %s has been deprecated and will be removed in a future version. Use %s instead.", name, normalizedName) + return pflag.NormalizedName(normalizedName) + } + return pflag.NormalizedName(name) +} + +// InitFlags normalizes, parses, then logs the command line flags. +func InitFlags() { + pflag.CommandLine.SetNormalizeFunc(WordSepNormalizeFunc) + pflag.CommandLine.AddGoFlagSet(goFlag.CommandLine) +} + +// PrintFlags logs the flags in the flagset. +func PrintFlags(flags *pflag.FlagSet) { + flags.VisitAll(func(flag *pflag.Flag) { + log.Printf("FLAG: --%s=%q", flag.Name, flag.Value) + }) +} diff --git a/pkg/util/genutil/genutil.go b/pkg/util/genutil/genutil.go new file mode 100644 index 000000000..36da89bbb --- /dev/null +++ b/pkg/util/genutil/genutil.go @@ -0,0 +1,27 @@ +package genutil + +import ( + "fmt" + "os" + "path/filepath" +) + +// OutDir creates the absolute path name from path and checks path exists. +// Returns absolute path including trailing '/' or error if path does not exist. +func OutDir(path string) (string, error) { + outDir, err := filepath.Abs(path) + if err != nil { + return "", err + } + + stat, err := os.Stat(outDir) + if err != nil { + return "", err + } + + if !stat.IsDir() { + return "", fmt.Errorf("output directory %s is not a directory", outDir) + } + outDir += "/" + return outDir, nil +} diff --git a/pkg/util/genutil/genutil_test.go b/pkg/util/genutil/genutil_test.go new file mode 100644 index 000000000..0ee85df27 --- /dev/null +++ b/pkg/util/genutil/genutil_test.go @@ -0,0 +1,26 @@ +package genutil + +import ( + "testing" +) + +func TestValidDir(t *testing.T) { + _, err := OutDir("./") + if err != nil { + t.Fatal(err) + } +} + +func TestInvalidDir(t *testing.T) { + _, err := OutDir("./nondir") + if err == nil { + t.Fatal("expected an error") + } +} + +func TestNotDir(t *testing.T) { + _, err := OutDir("./genutils_test.go") + if err == nil { + t.Fatal("expected an error") + } +} diff --git a/scripts/docker-start-all.sh b/scripts/docker-start-all.sh index 2616b7bd1..162655553 100755 --- a/scripts/docker-start-all.sh +++ b/scripts/docker-start-all.sh @@ -28,8 +28,6 @@ openim::log::info "\n# Use Docker to start all openim service" trap 'openim::util::onCtrlC' INT -"${OPENIM_ROOT}"/scripts/init-config.sh --skip - "${OPENIM_ROOT}"/scripts/start-all.sh sleep 5 diff --git a/scripts/install/openim-msgtransfer.sh b/scripts/install/openim-msgtransfer.sh index 18bbb3c02..f6039637c 100755 --- a/scripts/install/openim-msgtransfer.sh +++ b/scripts/install/openim-msgtransfer.sh @@ -12,6 +12,8 @@ # 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. +# Use: +# ./scripts/install/openim-msgtransfer.sh openim::msgtransfer::start # Common utilities, variables and checks for all build scripts. set -o errexit @@ -64,15 +66,20 @@ function openim::msgtransfer::check() { PIDS=$(pgrep -f "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer") NUM_PROCESSES=$(echo "$PIDS" | wc -l) - # NUM_PROCESSES=$(($NUM_PROCESSES - 1)) if [ "$NUM_PROCESSES" -eq "$OPENIM_MSGGATEWAY_NUM" ]; then - openim::log::info "Found $OPENIM_MSGGATEWAY_NUM processes named $OPENIM_OUTPUT_HOSTBIN" - for PID in $PIDS; do - ps -p $PID -o pid,cmd - done + openim::log::info "Found $OPENIM_MSGGATEWAY_NUM processes named $OPENIM_OUTPUT_HOSTBIN" + for PID in $PIDS; do + if [[ "$OSTYPE" == "linux-gnu"* ]]; then + ps -p $PID -o pid,cmd + elif [[ "$OSTYPE" == "darwin"* ]]; then + ps -p $PID -o pid,comm + else + openim::log::error "Unsupported OS type: $OSTYPE" + fi + done else - openim::log::error_exit "Expected $OPENIM_MSGGATEWAY_NUM openim msgtransfer processes, but found $NUM_PROCESSES msgtransfer processes." + openim::log::error_exit "Expected $OPENIM_MSGGATEWAY_NUM openim msgtransfer processes, but found $NUM_PROCESSES msgtransfer processes." fi } diff --git a/scripts/install/openim-rpc.sh b/scripts/install/openim-rpc.sh index b66004191..db1526d6a 100755 --- a/scripts/install/openim-rpc.sh +++ b/scripts/install/openim-rpc.sh @@ -123,12 +123,13 @@ function openim::rpc::start() { for ((i = 0; i < ${#OPENIM_RPC_SERVICE_LISTARIES[*]}; i++)); do # openim::util::stop_services_with_name ${OPENIM_RPC_SERVICE_LISTARIES openim::util::stop_services_on_ports ${OPENIM_RPC_PORT_LISTARIES[$i]} + openim::log::info "OpenIM ${OPENIM_RPC_SERVICE_LISTARIES[$i]} config path: ${OPENIM_RPC_CONFIG}" # Get the service and Prometheus ports. OPENIM_RPC_SERVICE_PORTS=( $(openim::util::list-to-string ${OPENIM_RPC_PORT_LISTARIES[$i]}) ) read -a OPENIM_RPC_SERVICE_PORTS_ARRAY <<< ${OPENIM_RPC_SERVICE_PORTS} - + OPENIM_RPC_PROM_PORTS=( $(openim::util::list-to-string ${OPENIM_RPC_PROM_PORT_LISTARIES[$i]}) ) read -a OPENIM_RPC_PROM_PORTS_ARRAY <<< ${OPENIM_RPC_PROM_PORTS} diff --git a/scripts/start-all.sh b/scripts/start-all.sh index 64b931f50..b1f9b865b 100755 --- a/scripts/start-all.sh +++ b/scripts/start-all.sh @@ -32,6 +32,8 @@ if [[ $? -ne 0 ]]; then fi set -o errexit +"${OPENIM_ROOT}"/scripts/init-config.sh --skip + echo "You need to start the following scripts in order: ${OPENIM_SERVER_SCRIPTARIES[@]}" openim::log::install_errexit