Merge branch 'openimsdk:main' into main

pull/1822/head
chao 9 months ago committed by GitHub
commit c81e199698
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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",

@ -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*.

@ -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:

@ -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:

@ -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/<your-username>/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=<your-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 `<your-username>` and `<your-ip>` 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.

@ -4,7 +4,7 @@ go 1.19
require (
firebase.google.com/go v3.13.0+incompatible
github.com/OpenIMSDK/protocol v0.0.47
github.com/OpenIMSDK/protocol v0.0.48
github.com/OpenIMSDK/tools v0.0.23
github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/dtm-labs/rockscache v0.1.1
@ -131,8 +131,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
@ -153,9 +153,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/protocol v0.0.47 => github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94
)
replace github.com/OpenIMSDK/protocol v0.0.47 => github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94

@ -15,11 +15,11 @@ cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/o
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
firebase.google.com/go v3.13.0+incompatible h1:3TdYC3DDi6aHn20qoRkxwGqNgdjtblwVAyRLQwGn/+4=
firebase.google.com/go v3.13.0+incompatible/go.mod h1:xlah6XbEyW6tbfSklcfe5FHJIwjt8toICdV5Wh9ptHs=
github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94 h1:o86vkek41ZrQqoBGqyKvS0z6N0uJj64mpzK72OkDZVM=
github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/IBM/sarama v1.41.3 h1:MWBEJ12vHC8coMjdEXFq/6ftO6DUZnQlFYcxtOJFa7c=
github.com/IBM/sarama v1.41.3/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
github.com/OpenIMSDK/protocol v0.0.47 h1:DTJMFSONzqT0i/wa4Q1CtDT/jVATVudIRHcpY1zSWYE=
github.com/OpenIMSDK/protocol v0.0.47/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
github.com/OpenIMSDK/tools v0.0.23 h1:xozfrGzhbpNPlDTap5DLVPk+JfgZ/ZyIj4Cuu3/bm9w=
github.com/OpenIMSDK/tools v0.0.23/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
@ -371,8 +371,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=
@ -438,12 +438,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=
@ -451,8 +451,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=

@ -124,6 +124,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

@ -229,14 +229,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
}

@ -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 {

@ -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 {

@ -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,8 @@ 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.

@ -89,7 +89,7 @@ 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 +98,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})

@ -57,7 +57,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)

@ -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)
})
}

@ -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
}

@ -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")
}
}

@ -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

@ -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
}

@ -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}

@ -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

Loading…
Cancel
Save