复制项目

This commit is contained in:
kim.dev.6789
2026-01-14 22:16:44 +08:00
parent e2577b8cee
commit e50142a3b9
691 changed files with 97009 additions and 1 deletions

979
pkg/common/config/config.go Normal file
View File

@@ -0,0 +1,979 @@
// 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.
package config
import (
"strings"
"time"
"github.com/openimsdk/tools/db/mongoutil"
"github.com/openimsdk/tools/db/redisutil"
"github.com/openimsdk/tools/mq/kafka"
"github.com/openimsdk/tools/s3/aws"
"github.com/openimsdk/tools/s3/cos"
"github.com/openimsdk/tools/s3/kodo"
"github.com/openimsdk/tools/s3/minio"
"github.com/openimsdk/tools/s3/oss"
)
const StructTagName = "yaml"
type Path string
type Index int
type CacheConfig struct {
Topic string `yaml:"topic"`
SlotNum int `yaml:"slotNum"`
SlotSize int `yaml:"slotSize"`
SuccessExpire int `yaml:"successExpire"`
FailedExpire int `yaml:"failedExpire"`
}
type LocalCache struct {
Auth CacheConfig `yaml:"auth"`
User CacheConfig `yaml:"user"`
Group CacheConfig `yaml:"group"`
Friend CacheConfig `yaml:"friend"`
Conversation CacheConfig `yaml:"conversation"`
}
type Log struct {
StorageLocation string `yaml:"storageLocation"`
RotationTime uint `yaml:"rotationTime"`
RemainRotationCount uint `yaml:"remainRotationCount"`
RemainLogLevel int `yaml:"remainLogLevel"`
IsStdout bool `yaml:"isStdout"`
IsJson bool `yaml:"isJson"`
IsSimplify bool `yaml:"isSimplify"`
WithStack bool `yaml:"withStack"`
}
type Minio struct {
Bucket string `yaml:"bucket"`
AccessKeyID string `yaml:"accessKeyID"`
SecretAccessKey string `yaml:"secretAccessKey"`
SessionToken string `yaml:"sessionToken"`
InternalAddress string `yaml:"internalAddress"`
ExternalAddress string `yaml:"externalAddress"`
PublicRead bool `yaml:"publicRead"`
}
type Mongo struct {
URI string `yaml:"uri"`
Address []string `yaml:"address"`
Database string `yaml:"database"`
Username string `yaml:"username"`
Password string `yaml:"password"`
AuthSource string `yaml:"authSource"`
MaxPoolSize int `yaml:"maxPoolSize"`
MaxRetry int `yaml:"maxRetry"`
MongoMode string `yaml:"mongoMode"`
ReplicaSet ReplicaSetConfig
ReadPreference ReadPrefConfig
WriteConcern WriteConcernConfig
}
type ReplicaSetConfig struct {
Name string `yaml:"name"`
Hosts []string `yaml:"hosts"`
ReadConcern string `yaml:"readConcern"`
MaxStaleness time.Duration `yaml:"maxStaleness"`
}
type ReadPrefConfig struct {
Mode string `yaml:"mode"`
TagSets []map[string]string `yaml:"tagSets"`
MaxStaleness time.Duration `yaml:"maxStaleness"`
}
type WriteConcernConfig struct {
W any `yaml:"w"`
J bool `yaml:"j"`
WTimeout time.Duration `yaml:"wtimeout"`
}
type Kafka struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
ProducerAck string `yaml:"producerAck"`
CompressType string `yaml:"compressType"`
Address []string `yaml:"address"`
ToRedisTopic string `yaml:"toRedisTopic"`
ToMongoTopic string `yaml:"toMongoTopic"`
ToPushTopic string `yaml:"toPushTopic"`
ToOfflinePushTopic string `yaml:"toOfflinePushTopic"`
ToRedisGroupID string `yaml:"toRedisGroupID"`
ToMongoGroupID string `yaml:"toMongoGroupID"`
ToPushGroupID string `yaml:"toPushGroupID"`
ToOfflineGroupID string `yaml:"toOfflinePushGroupID"`
Tls TLSConfig `yaml:"tls"`
}
type TLSConfig struct {
EnableTLS bool `yaml:"enableTLS"`
CACrt string `yaml:"caCrt"`
ClientCrt string `yaml:"clientCrt"`
ClientKey string `yaml:"clientKey"`
ClientKeyPwd string `yaml:"clientKeyPwd"`
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
}
type API struct {
Api struct {
ListenIP string `yaml:"listenIP"`
Ports []int `yaml:"ports"`
CompressionLevel int `yaml:"compressionLevel"`
} `yaml:"api"`
Prometheus struct {
Enable bool `yaml:"enable"`
AutoSetPorts bool `yaml:"autoSetPorts"`
Ports []int `yaml:"ports"`
GrafanaURL string `yaml:"grafanaURL"`
} `yaml:"prometheus"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
OnlineCountRefresh struct {
Enable bool `yaml:"enable"`
Interval time.Duration `yaml:"interval"`
} `yaml:"onlineCountRefresh"`
}
type CronTask struct {
CronExecuteTime string `yaml:"cronExecuteTime"`
RetainChatRecords int `yaml:"retainChatRecords"`
FileExpireTime int `yaml:"fileExpireTime"`
DeleteObjectType []string `yaml:"deleteObjectType"`
}
type OfflinePushConfig struct {
Enable bool `yaml:"enable"`
Title string `yaml:"title"`
Desc string `yaml:"desc"`
Ext string `yaml:"ext"`
}
type NotificationConfig struct {
IsSendMsg bool `yaml:"isSendMsg"`
ReliabilityLevel int `yaml:"reliabilityLevel"`
UnreadCount bool `yaml:"unreadCount"`
OfflinePush OfflinePushConfig `yaml:"offlinePush"`
}
type Notification struct {
GroupCreated NotificationConfig `yaml:"groupCreated"`
GroupInfoSet NotificationConfig `yaml:"groupInfoSet"`
JoinGroupApplication NotificationConfig `yaml:"joinGroupApplication"`
MemberQuit NotificationConfig `yaml:"memberQuit"`
GroupApplicationAccepted NotificationConfig `yaml:"groupApplicationAccepted"`
GroupApplicationRejected NotificationConfig `yaml:"groupApplicationRejected"`
GroupOwnerTransferred NotificationConfig `yaml:"groupOwnerTransferred"`
MemberKicked NotificationConfig `yaml:"memberKicked"`
MemberInvited NotificationConfig `yaml:"memberInvited"`
MemberEnter NotificationConfig `yaml:"memberEnter"`
GroupDismissed NotificationConfig `yaml:"groupDismissed"`
GroupMuted NotificationConfig `yaml:"groupMuted"`
GroupCancelMuted NotificationConfig `yaml:"groupCancelMuted"`
GroupMemberMuted NotificationConfig `yaml:"groupMemberMuted"`
GroupMemberCancelMuted NotificationConfig `yaml:"groupMemberCancelMuted"`
GroupMemberInfoSet NotificationConfig `yaml:"groupMemberInfoSet"`
GroupMemberSetToAdmin NotificationConfig `yaml:"groupMemberSetToAdmin"`
GroupMemberSetToOrdinary NotificationConfig `yaml:"groupMemberSetToOrdinaryUser"`
GroupInfoSetAnnouncement NotificationConfig `yaml:"groupInfoSetAnnouncement"`
GroupInfoSetName NotificationConfig `yaml:"groupInfoSetName"`
FriendApplicationAdded NotificationConfig `yaml:"friendApplicationAdded"`
FriendApplicationApproved NotificationConfig `yaml:"friendApplicationApproved"`
FriendApplicationRejected NotificationConfig `yaml:"friendApplicationRejected"`
FriendAdded NotificationConfig `yaml:"friendAdded"`
FriendDeleted NotificationConfig `yaml:"friendDeleted"`
FriendRemarkSet NotificationConfig `yaml:"friendRemarkSet"`
BlackAdded NotificationConfig `yaml:"blackAdded"`
BlackDeleted NotificationConfig `yaml:"blackDeleted"`
FriendInfoUpdated NotificationConfig `yaml:"friendInfoUpdated"`
UserInfoUpdated NotificationConfig `yaml:"userInfoUpdated"`
UserStatusChanged NotificationConfig `yaml:"userStatusChanged"`
ConversationChanged NotificationConfig `yaml:"conversationChanged"`
ConversationSetPrivate NotificationConfig `yaml:"conversationSetPrivate"`
}
type Prometheus struct {
Enable bool `yaml:"enable"`
Ports []int `yaml:"ports"`
}
type MsgGateway struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
ListenIP string `yaml:"listenIP"`
LongConnSvr struct {
Ports []int `yaml:"ports"`
WebsocketMaxConnNum int `yaml:"websocketMaxConnNum"`
WebsocketMaxMsgLen int `yaml:"websocketMaxMsgLen"`
WebsocketTimeout int `yaml:"websocketTimeout"`
} `yaml:"longConnSvr"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type MsgTransfer struct {
Prometheus struct {
Enable bool `yaml:"enable"`
AutoSetPorts bool `yaml:"autoSetPorts"`
Ports []int `yaml:"ports"`
} `yaml:"prometheus"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Push struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
MaxConcurrentWorkers int `yaml:"maxConcurrentWorkers"`
Enable string `yaml:"enable"`
GeTui struct {
PushUrl string `yaml:"pushUrl"`
MasterSecret string `yaml:"masterSecret"`
AppKey string `yaml:"appKey"`
Intent string `yaml:"intent"`
ChannelID string `yaml:"channelID"`
ChannelName string `yaml:"channelName"`
} `yaml:"geTui"`
FCM struct {
FilePath string `yaml:"filePath"`
AuthURL string `yaml:"authURL"`
} `yaml:"fcm"`
JPush struct {
AppKey string `yaml:"appKey"`
MasterSecret string `yaml:"masterSecret"`
PushURL string `yaml:"pushURL"`
PushIntent string `yaml:"pushIntent"`
} `yaml:"jpush"`
IOSPush struct {
PushSound string `yaml:"pushSound"`
BadgeCount bool `yaml:"badgeCount"`
Production bool `yaml:"production"`
} `yaml:"iosPush"`
FullUserCache bool `yaml:"fullUserCache"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Auth struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
TokenPolicy struct {
Expire int64 `yaml:"expire"`
} `yaml:"tokenPolicy"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Conversation struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Friend struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Group struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
EnableHistoryForNewMembers bool `yaml:"enableHistoryForNewMembers"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Msg struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
FriendVerify bool `yaml:"friendVerify"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Third struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
Object struct {
Enable string `yaml:"enable"`
Cos Cos `yaml:"cos"`
Oss Oss `yaml:"oss"`
Kodo Kodo `yaml:"kodo"`
Aws Aws `yaml:"aws"`
} `yaml:"object"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type Cos struct {
BucketURL string `yaml:"bucketURL"`
SecretID string `yaml:"secretID"`
SecretKey string `yaml:"secretKey"`
SessionToken string `yaml:"sessionToken"`
PublicRead bool `yaml:"publicRead"`
}
type Oss struct {
Endpoint string `yaml:"endpoint"`
Bucket string `yaml:"bucket"`
BucketURL string `yaml:"bucketURL"`
AccessKeyID string `yaml:"accessKeyID"`
AccessKeySecret string `yaml:"accessKeySecret"`
SessionToken string `yaml:"sessionToken"`
PublicRead bool `yaml:"publicRead"`
}
type Kodo struct {
Endpoint string `yaml:"endpoint"`
Bucket string `yaml:"bucket"`
BucketURL string `yaml:"bucketURL"`
AccessKeyID string `yaml:"accessKeyID"`
AccessKeySecret string `yaml:"accessKeySecret"`
SessionToken string `yaml:"sessionToken"`
PublicRead bool `yaml:"publicRead"`
}
type Aws struct {
Region string `yaml:"region"`
Bucket string `yaml:"bucket"`
Endpoint string `yaml:"endpoint"`
AccessKeyID string `yaml:"accessKeyID"`
SecretAccessKey string `yaml:"secretAccessKey"`
SessionToken string `yaml:"sessionToken"`
PublicRead bool `yaml:"publicRead"`
}
type User struct {
RPC RPC `yaml:"rpc"`
Prometheus Prometheus `yaml:"prometheus"`
RateLimiter RateLimiter `yaml:"ratelimiter"`
CircuitBreaker CircuitBreaker `yaml:"circuitBreaker"`
}
type RPC struct {
RegisterIP string `yaml:"registerIP"`
ListenIP string `yaml:"listenIP"`
AutoSetPorts bool `yaml:"autoSetPorts"`
Ports []int `yaml:"ports"`
}
type Redis struct {
Disable bool `yaml:"-"`
Address []string `yaml:"address"`
Username string `yaml:"username"`
Password string `yaml:"password"`
RedisMode string `yaml:"redisMode"`
DB int `yaml:"db"`
MaxRetry int `yaml:"maxRetry"`
PoolSize int `yaml:"poolSize"`
OnlineKeyPrefix string `yaml:"onlineKeyPrefix"`
OnlineKeyPrefixHashTag bool `yaml:"onlineKeyPrefixHashTag"`
SentinelMode Sentinel `yaml:"sentinelMode"`
}
type Sentinel struct {
MasterName string `yaml:"masterName"`
SentinelAddrs []string `yaml:"sentinelsAddrs"`
RouteByLatency bool `yaml:"routeByLatency"`
RouteRandomly bool `yaml:"routeRandomly"`
}
type BeforeConfig struct {
Enable bool `yaml:"enable"`
Timeout int `yaml:"timeout"`
FailedContinue bool `yaml:"failedContinue"`
DeniedTypes []int32 `yaml:"deniedTypes"`
}
type AfterConfig struct {
Enable bool `yaml:"enable"`
Timeout int `yaml:"timeout"`
AttentionIds []string `yaml:"attentionIds"`
DeniedTypes []int32 `yaml:"deniedTypes"`
}
type RateLimiter struct {
Enable bool `yaml:"enable"`
Window time.Duration `yaml:"window"`
Bucket int `yaml:"bucket"`
CPUThreshold int64 `yaml:"cpuThreshold"`
}
type CircuitBreaker struct {
Enable bool `yaml:"enable"`
Window time.Duration `yaml:"window"`
Bucket int `yaml:"bucket"`
Success float64 `yaml:"success"`
Request int64 `yaml:"request"`
}
type Share struct {
Secret string `yaml:"secret"`
IMAdminUser struct {
UserIDs []string `yaml:"userIDs"`
Nicknames []string `yaml:"nicknames"`
} `yaml:"imAdminUser"`
MultiLogin MultiLogin `yaml:"multiLogin"`
RPCMaxBodySize MaxRequestBody `yaml:"rpcMaxBodySize"`
}
type MaxRequestBody struct {
RequestMaxBodySize int `yaml:"requestMaxBodySize"`
ResponseMaxBodySize int `yaml:"responseMaxBodySize"`
}
type MultiLogin struct {
Policy int `yaml:"policy"`
MaxNumOneEnd int `yaml:"maxNumOneEnd"`
}
type RpcService struct {
User string `yaml:"user"`
Friend string `yaml:"friend"`
Msg string `yaml:"msg"`
Push string `yaml:"push"`
MessageGateway string `yaml:"messageGateway"`
Group string `yaml:"group"`
Auth string `yaml:"auth"`
Conversation string `yaml:"conversation"`
Third string `yaml:"third"`
}
func (r *RpcService) GetServiceNames() []string {
return []string{
r.User,
r.Friend,
r.Msg,
r.Push,
r.MessageGateway,
r.Group,
r.Auth,
r.Conversation,
r.Third,
}
}
// FullConfig stores all configurations for before and after events
type Webhooks struct {
URL string `yaml:"url"`
BeforeSendSingleMsg BeforeConfig `yaml:"beforeSendSingleMsg"`
BeforeUpdateUserInfoEx BeforeConfig `yaml:"beforeUpdateUserInfoEx"`
AfterUpdateUserInfoEx AfterConfig `yaml:"afterUpdateUserInfoEx"`
AfterSendSingleMsg AfterConfig `yaml:"afterSendSingleMsg"`
BeforeSendGroupMsg BeforeConfig `yaml:"beforeSendGroupMsg"`
BeforeMsgModify BeforeConfig `yaml:"beforeMsgModify"`
AfterSendGroupMsg AfterConfig `yaml:"afterSendGroupMsg"`
AfterMsgSaveDB AfterConfig `yaml:"afterMsgSaveDB"`
AfterUserOnline AfterConfig `yaml:"afterUserOnline"`
AfterUserOffline AfterConfig `yaml:"afterUserOffline"`
AfterUserKickOff AfterConfig `yaml:"afterUserKickOff"`
BeforeOfflinePush BeforeConfig `yaml:"beforeOfflinePush"`
BeforeOnlinePush BeforeConfig `yaml:"beforeOnlinePush"`
BeforeGroupOnlinePush BeforeConfig `yaml:"beforeGroupOnlinePush"`
BeforeAddFriend BeforeConfig `yaml:"beforeAddFriend"`
BeforeUpdateUserInfo BeforeConfig `yaml:"beforeUpdateUserInfo"`
AfterUpdateUserInfo AfterConfig `yaml:"afterUpdateUserInfo"`
BeforeCreateGroup BeforeConfig `yaml:"beforeCreateGroup"`
AfterCreateGroup AfterConfig `yaml:"afterCreateGroup"`
BeforeMemberJoinGroup BeforeConfig `yaml:"beforeMemberJoinGroup"`
BeforeSetGroupMemberInfo BeforeConfig `yaml:"beforeSetGroupMemberInfo"`
AfterSetGroupMemberInfo AfterConfig `yaml:"afterSetGroupMemberInfo"`
AfterQuitGroup AfterConfig `yaml:"afterQuitGroup"`
AfterKickGroupMember AfterConfig `yaml:"afterKickGroupMember"`
AfterDismissGroup AfterConfig `yaml:"afterDismissGroup"`
BeforeApplyJoinGroup BeforeConfig `yaml:"beforeApplyJoinGroup"`
AfterGroupMsgRead AfterConfig `yaml:"afterGroupMsgRead"`
AfterSingleMsgRead AfterConfig `yaml:"afterSingleMsgRead"`
BeforeUserRegister BeforeConfig `yaml:"beforeUserRegister"`
AfterUserRegister AfterConfig `yaml:"afterUserRegister"`
AfterTransferGroupOwner AfterConfig `yaml:"afterTransferGroupOwner"`
BeforeSetFriendRemark BeforeConfig `yaml:"beforeSetFriendRemark"`
AfterSetFriendRemark AfterConfig `yaml:"afterSetFriendRemark"`
AfterGroupMsgRevoke AfterConfig `yaml:"afterGroupMsgRevoke"`
AfterJoinGroup AfterConfig `yaml:"afterJoinGroup"`
BeforeInviteUserToGroup BeforeConfig `yaml:"beforeInviteUserToGroup"`
AfterSetGroupInfo AfterConfig `yaml:"afterSetGroupInfo"`
BeforeSetGroupInfo BeforeConfig `yaml:"beforeSetGroupInfo"`
AfterSetGroupInfoEx AfterConfig `yaml:"afterSetGroupInfoEx"`
BeforeSetGroupInfoEx BeforeConfig `yaml:"beforeSetGroupInfoEx"`
AfterRevokeMsg AfterConfig `yaml:"afterRevokeMsg"`
BeforeAddBlack BeforeConfig `yaml:"beforeAddBlack"`
AfterAddFriend AfterConfig `yaml:"afterAddFriend"`
BeforeAddFriendAgree BeforeConfig `yaml:"beforeAddFriendAgree"`
AfterAddFriendAgree AfterConfig `yaml:"afterAddFriendAgree"`
AfterDeleteFriend AfterConfig `yaml:"afterDeleteFriend"`
BeforeImportFriends BeforeConfig `yaml:"beforeImportFriends"`
AfterImportFriends AfterConfig `yaml:"afterImportFriends"`
AfterRemoveBlack AfterConfig `yaml:"afterRemoveBlack"`
BeforeCreateSingleChatConversations BeforeConfig `yaml:"beforeCreateSingleChatConversations"`
AfterCreateSingleChatConversations AfterConfig `yaml:"afterCreateSingleChatConversations"`
BeforeCreateGroupChatConversations BeforeConfig `yaml:"beforeCreateGroupChatConversations"`
AfterCreateGroupChatConversations AfterConfig `yaml:"afterCreateGroupChatConversations"`
}
type ZooKeeper struct {
Schema string `yaml:"schema"`
Address []string `yaml:"address"`
Username string `yaml:"username"`
Password string `yaml:"password"`
}
type Discovery struct {
Enable string `yaml:"enable"`
Etcd Etcd `yaml:"etcd"`
Kubernetes Kubernetes `yaml:"kubernetes"`
RpcService RpcService `yaml:"rpcService"`
}
type Kubernetes struct {
Namespace string `yaml:"namespace"`
}
type Etcd struct {
RootDirectory string `yaml:"rootDirectory"`
Address []string `yaml:"address"`
Username string `yaml:"username"`
Password string `yaml:"password"`
}
func (m *Mongo) Build() *mongoutil.Config {
return &mongoutil.Config{
Uri: m.URI,
Address: m.Address,
Database: m.Database,
Username: m.Username,
Password: m.Password,
AuthSource: m.AuthSource,
MaxPoolSize: m.MaxPoolSize,
MaxRetry: m.MaxRetry,
MongoMode: m.MongoMode,
ReplicaSet: &mongoutil.ReplicaSetConfig{
Name: m.ReplicaSet.Name,
Hosts: m.ReplicaSet.Hosts,
ReadConcern: m.ReplicaSet.ReadConcern,
MaxStaleness: m.ReplicaSet.MaxStaleness,
},
ReadPreference: &mongoutil.ReadPrefConfig{
Mode: m.ReadPreference.Mode,
TagSets: m.ReadPreference.TagSets,
MaxStaleness: m.ReadPreference.MaxStaleness,
},
WriteConcern: &mongoutil.WriteConcernConfig{
W: m.WriteConcern.W,
J: m.WriteConcern.J,
WTimeout: m.WriteConcern.WTimeout,
},
}
}
func (r *Redis) Build() *redisutil.Config {
return &redisutil.Config{
RedisMode: r.RedisMode,
Address: r.Address,
Username: r.Username,
Password: r.Password,
DB: r.DB,
MaxRetry: r.MaxRetry,
PoolSize: r.PoolSize,
Sentinel: &redisutil.Sentinel{
MasterName: r.SentinelMode.MasterName,
SentinelAddrs: r.SentinelMode.SentinelAddrs,
RouteByLatency: r.SentinelMode.RouteByLatency,
RouteRandomly: r.SentinelMode.RouteRandomly,
},
}
}
func (k *Kafka) Build() *kafka.Config {
return &kafka.Config{
Username: k.Username,
Password: k.Password,
ProducerAck: k.ProducerAck,
CompressType: k.CompressType,
Addr: k.Address,
TLS: kafka.TLSConfig{
EnableTLS: k.Tls.EnableTLS,
CACrt: k.Tls.CACrt,
ClientCrt: k.Tls.ClientCrt,
ClientKey: k.Tls.ClientKey,
ClientKeyPwd: k.Tls.ClientKeyPwd,
InsecureSkipVerify: k.Tls.InsecureSkipVerify,
},
}
}
func (m *Minio) Build() *minio.Config {
formatEndpoint := func(address string) string {
if strings.HasPrefix(address, "http://") || strings.HasPrefix(address, "https://") {
return address
}
return "http://" + address
}
return &minio.Config{
Bucket: m.Bucket,
AccessKeyID: m.AccessKeyID,
SecretAccessKey: m.SecretAccessKey,
SessionToken: m.SessionToken,
PublicRead: m.PublicRead,
Endpoint: formatEndpoint(m.InternalAddress),
SignEndpoint: formatEndpoint(m.ExternalAddress),
}
}
func (c *Cos) Build() *cos.Config {
return &cos.Config{
BucketURL: c.BucketURL,
SecretID: c.SecretID,
SecretKey: c.SecretKey,
SessionToken: c.SessionToken,
PublicRead: c.PublicRead,
}
}
func (o *Oss) Build() *oss.Config {
return &oss.Config{
Endpoint: o.Endpoint,
Bucket: o.Bucket,
BucketURL: o.BucketURL,
AccessKeyID: o.AccessKeyID,
AccessKeySecret: o.AccessKeySecret,
SessionToken: o.SessionToken,
PublicRead: o.PublicRead,
}
}
func (o *Kodo) Build() *kodo.Config {
return &kodo.Config{
Endpoint: o.Endpoint,
Bucket: o.Bucket,
BucketURL: o.BucketURL,
AccessKeyID: o.AccessKeyID,
AccessKeySecret: o.AccessKeySecret,
SessionToken: o.SessionToken,
PublicRead: o.PublicRead,
}
}
func (o *Aws) Build() *aws.Config {
return &aws.Config{
Region: o.Region,
Bucket: o.Bucket,
AccessKeyID: o.AccessKeyID,
SecretAccessKey: o.SecretAccessKey,
SessionToken: o.SessionToken,
}
}
func (l *CacheConfig) Failed() time.Duration {
return time.Second * time.Duration(l.FailedExpire)
}
func (l *CacheConfig) Success() time.Duration {
return time.Second * time.Duration(l.SuccessExpire)
}
func (l *CacheConfig) Enable() bool {
return l.Topic != "" && l.SlotNum > 0 && l.SlotSize > 0
}
func InitNotification(notification *Notification) {
notification.GroupCreated.UnreadCount = false
notification.GroupCreated.ReliabilityLevel = 1
notification.GroupInfoSet.UnreadCount = false
notification.GroupInfoSet.ReliabilityLevel = 1
notification.JoinGroupApplication.UnreadCount = false
notification.JoinGroupApplication.ReliabilityLevel = 1
notification.MemberQuit.UnreadCount = false
notification.MemberQuit.ReliabilityLevel = 1
notification.GroupApplicationAccepted.UnreadCount = false
notification.GroupApplicationAccepted.ReliabilityLevel = 1
notification.GroupApplicationRejected.UnreadCount = false
notification.GroupApplicationRejected.ReliabilityLevel = 1
notification.GroupOwnerTransferred.UnreadCount = false
notification.GroupOwnerTransferred.ReliabilityLevel = 1
notification.MemberKicked.UnreadCount = false
notification.MemberKicked.ReliabilityLevel = 1
notification.MemberInvited.UnreadCount = false
notification.MemberInvited.ReliabilityLevel = 1
notification.MemberEnter.UnreadCount = false
notification.MemberEnter.ReliabilityLevel = 1
notification.GroupDismissed.UnreadCount = false
notification.GroupDismissed.ReliabilityLevel = 1
notification.GroupMuted.UnreadCount = false
notification.GroupMuted.ReliabilityLevel = 1
notification.GroupCancelMuted.UnreadCount = false
notification.GroupCancelMuted.ReliabilityLevel = 1
notification.GroupMemberMuted.UnreadCount = false
notification.GroupMemberMuted.ReliabilityLevel = 1
notification.GroupMemberCancelMuted.UnreadCount = false
notification.GroupMemberCancelMuted.ReliabilityLevel = 1
notification.GroupMemberInfoSet.UnreadCount = false
notification.GroupMemberInfoSet.ReliabilityLevel = 1
notification.GroupMemberSetToAdmin.UnreadCount = false
notification.GroupMemberSetToAdmin.ReliabilityLevel = 1
notification.GroupMemberSetToOrdinary.UnreadCount = false
notification.GroupMemberSetToOrdinary.ReliabilityLevel = 1
notification.GroupInfoSetAnnouncement.UnreadCount = false
notification.GroupInfoSetAnnouncement.ReliabilityLevel = 1
notification.GroupInfoSetName.UnreadCount = false
notification.GroupInfoSetName.ReliabilityLevel = 1
notification.FriendApplicationAdded.UnreadCount = false
notification.FriendApplicationAdded.ReliabilityLevel = 1
notification.FriendApplicationApproved.UnreadCount = false
notification.FriendApplicationApproved.ReliabilityLevel = 1
notification.FriendApplicationRejected.UnreadCount = false
notification.FriendApplicationRejected.ReliabilityLevel = 1
notification.FriendAdded.UnreadCount = false
notification.FriendAdded.ReliabilityLevel = 1
notification.FriendDeleted.UnreadCount = false
notification.FriendDeleted.ReliabilityLevel = 1
notification.FriendRemarkSet.UnreadCount = false
notification.FriendRemarkSet.ReliabilityLevel = 1
notification.BlackAdded.UnreadCount = false
notification.BlackAdded.ReliabilityLevel = 1
notification.BlackDeleted.UnreadCount = false
notification.BlackDeleted.ReliabilityLevel = 1
notification.FriendInfoUpdated.UnreadCount = false
notification.FriendInfoUpdated.ReliabilityLevel = 1
notification.UserInfoUpdated.UnreadCount = false
notification.UserInfoUpdated.ReliabilityLevel = 1
notification.UserStatusChanged.UnreadCount = false
notification.UserStatusChanged.ReliabilityLevel = 1
notification.ConversationChanged.UnreadCount = false
notification.ConversationChanged.ReliabilityLevel = 1
notification.ConversationSetPrivate.UnreadCount = false
notification.ConversationSetPrivate.ReliabilityLevel = 1
}
type AllConfig struct {
Discovery Discovery
Kafka Kafka
LocalCache LocalCache
Log Log
Minio Minio
Mongo Mongo
Notification Notification
API API
CronTask CronTask
MsgGateway MsgGateway
MsgTransfer MsgTransfer
Push Push
Auth Auth
Conversation Conversation
Friend Friend
Group Group
Msg Msg
Third Third
User User
Redis Redis
Share Share
Webhooks Webhooks
}
func (a *AllConfig) Name2Config(name string) any {
switch name {
case a.Discovery.GetConfigFileName():
return a.Discovery
case a.Kafka.GetConfigFileName():
return a.Kafka
case a.LocalCache.GetConfigFileName():
return a.LocalCache
case a.Log.GetConfigFileName():
return a.Log
case a.Minio.GetConfigFileName():
return a.Minio
case a.Mongo.GetConfigFileName():
return a.Mongo
case a.Notification.GetConfigFileName():
return a.Notification
case a.API.GetConfigFileName():
return a.API
case a.CronTask.GetConfigFileName():
return a.CronTask
case a.MsgGateway.GetConfigFileName():
return a.MsgGateway
case a.MsgTransfer.GetConfigFileName():
return a.MsgTransfer
case a.Push.GetConfigFileName():
return a.Push
case a.Auth.GetConfigFileName():
return a.Auth
case a.Conversation.GetConfigFileName():
return a.Conversation
case a.Friend.GetConfigFileName():
return a.Friend
case a.Group.GetConfigFileName():
return a.Group
case a.Msg.GetConfigFileName():
return a.Msg
case a.Third.GetConfigFileName():
return a.Third
case a.User.GetConfigFileName():
return a.User
case a.Redis.GetConfigFileName():
return a.Redis
case a.Share.GetConfigFileName():
return a.Share
case a.Webhooks.GetConfigFileName():
return a.Webhooks
default:
return nil
}
}
func (a *AllConfig) GetConfigNames() []string {
return []string{
a.Discovery.GetConfigFileName(),
a.Kafka.GetConfigFileName(),
a.LocalCache.GetConfigFileName(),
a.Log.GetConfigFileName(),
a.Minio.GetConfigFileName(),
a.Mongo.GetConfigFileName(),
a.Notification.GetConfigFileName(),
a.API.GetConfigFileName(),
a.CronTask.GetConfigFileName(),
a.MsgGateway.GetConfigFileName(),
a.MsgTransfer.GetConfigFileName(),
a.Push.GetConfigFileName(),
a.Auth.GetConfigFileName(),
a.Conversation.GetConfigFileName(),
a.Friend.GetConfigFileName(),
a.Group.GetConfigFileName(),
a.Msg.GetConfigFileName(),
a.Third.GetConfigFileName(),
a.User.GetConfigFileName(),
a.Redis.GetConfigFileName(),
a.Share.GetConfigFileName(),
a.Webhooks.GetConfigFileName(),
}
}
const (
FileName = "config.yaml"
DiscoveryConfigFilename = "discovery.yml"
KafkaConfigFileName = "kafka.yml"
LocalCacheConfigFileName = "local-cache.yml"
LogConfigFileName = "log.yml"
MinioConfigFileName = "minio.yml"
MongodbConfigFileName = "mongodb.yml"
NotificationFileName = "notification.yml"
OpenIMAPICfgFileName = "openim-api.yml"
OpenIMCronTaskCfgFileName = "openim-crontask.yml"
OpenIMMsgGatewayCfgFileName = "openim-msggateway.yml"
OpenIMMsgTransferCfgFileName = "openim-msgtransfer.yml"
OpenIMPushCfgFileName = "openim-push.yml"
OpenIMRPCAuthCfgFileName = "openim-rpc-auth.yml"
OpenIMRPCConversationCfgFileName = "openim-rpc-conversation.yml"
OpenIMRPCFriendCfgFileName = "openim-rpc-friend.yml"
OpenIMRPCGroupCfgFileName = "openim-rpc-group.yml"
OpenIMRPCMsgCfgFileName = "openim-rpc-msg.yml"
OpenIMRPCThirdCfgFileName = "openim-rpc-third.yml"
OpenIMRPCUserCfgFileName = "openim-rpc-user.yml"
RedisConfigFileName = "redis.yml"
ShareFileName = "share.yml"
WebhooksConfigFileName = "webhooks.yml"
)
func (d *Discovery) GetConfigFileName() string {
return DiscoveryConfigFilename
}
func (k *Kafka) GetConfigFileName() string {
return KafkaConfigFileName
}
func (lc *LocalCache) GetConfigFileName() string {
return LocalCacheConfigFileName
}
func (l *Log) GetConfigFileName() string {
return LogConfigFileName
}
func (m *Minio) GetConfigFileName() string {
return MinioConfigFileName
}
func (m *Mongo) GetConfigFileName() string {
return MongodbConfigFileName
}
func (n *Notification) GetConfigFileName() string {
return NotificationFileName
}
func (a *API) GetConfigFileName() string {
return OpenIMAPICfgFileName
}
func (ct *CronTask) GetConfigFileName() string {
return OpenIMCronTaskCfgFileName
}
func (mg *MsgGateway) GetConfigFileName() string {
return OpenIMMsgGatewayCfgFileName
}
func (mt *MsgTransfer) GetConfigFileName() string {
return OpenIMMsgTransferCfgFileName
}
func (p *Push) GetConfigFileName() string {
return OpenIMPushCfgFileName
}
func (a *Auth) GetConfigFileName() string {
return OpenIMRPCAuthCfgFileName
}
func (c *Conversation) GetConfigFileName() string {
return OpenIMRPCConversationCfgFileName
}
func (f *Friend) GetConfigFileName() string {
return OpenIMRPCFriendCfgFileName
}
func (g *Group) GetConfigFileName() string {
return OpenIMRPCGroupCfgFileName
}
func (m *Msg) GetConfigFileName() string {
return OpenIMRPCMsgCfgFileName
}
func (t *Third) GetConfigFileName() string {
return OpenIMRPCThirdCfgFileName
}
func (u *User) GetConfigFileName() string {
return OpenIMRPCUserCfgFileName
}
func (r *Redis) GetConfigFileName() string {
return RedisConfigFileName
}
func (s *Share) GetConfigFileName() string {
return ShareFileName
}
func (w *Webhooks) GetConfigFileName() string {
return WebhooksConfigFileName
}

View File

@@ -0,0 +1,47 @@
// Copyright © 2024 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.
package config
import "github.com/openimsdk/tools/utils/runtimeenv"
const ConfKey = "conf"
const (
MountConfigFilePath = "CONFIG_PATH"
DeploymentType = "DEPLOYMENT_TYPE"
KUBERNETES = runtimeenv.Kubernetes
ETCD = "etcd"
//Standalone = "standalone"
)
const (
// DefaultDirPerm is used for creating general directories, allowing the owner to read, write, and execute,
// while the group and others can only read and execute.
DefaultDirPerm = 0755
// PrivateFilePerm is used for sensitive files, allowing only the owner to read and write.
PrivateFilePerm = 0600
// ExecFilePerm is used for executable files, allowing the owner to read, write, and execute,
// while the group and others can only read.
ExecFilePerm = 0754
// SharedDirPerm is used for shared directories, allowing the owner and group to read, write, and execute,
// with no permissions for others.
SharedDirPerm = 0770
// ReadOnlyDirPerm is used for read-only directories, allowing the owner, group, and others to only read.
ReadOnlyDirPerm = 0555
)

15
pkg/common/config/doc.go Normal file
View File

@@ -0,0 +1,15 @@
// Copyright © 2024 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.
package config // import "git.imall.cloud/openim/open-im-server-deploy/pkg/common/config"

30
pkg/common/config/env.go Normal file
View File

@@ -0,0 +1,30 @@
package config
import "strings"
var EnvPrefixMap map[string]string
func init() {
EnvPrefixMap = make(map[string]string)
fileNames := []string{
FileName, NotificationFileName, ShareFileName, WebhooksConfigFileName,
KafkaConfigFileName, RedisConfigFileName,
MongodbConfigFileName, MinioConfigFileName, LogConfigFileName,
OpenIMAPICfgFileName, OpenIMCronTaskCfgFileName, OpenIMMsgGatewayCfgFileName,
OpenIMMsgTransferCfgFileName, OpenIMPushCfgFileName, OpenIMRPCAuthCfgFileName,
OpenIMRPCConversationCfgFileName, OpenIMRPCFriendCfgFileName, OpenIMRPCGroupCfgFileName,
OpenIMRPCMsgCfgFileName, OpenIMRPCThirdCfgFileName, OpenIMRPCUserCfgFileName, DiscoveryConfigFilename,
}
for _, fileName := range fileNames {
envKey := strings.TrimSuffix(strings.TrimSuffix(fileName, ".yml"), ".yaml")
envKey = "IMENV_" + envKey
envKey = strings.ToUpper(strings.ReplaceAll(envKey, "-", "_"))
EnvPrefixMap[fileName] = envKey
}
}
const (
FlagConf = "config_folder_path"
FlagTransferIndex = "index"
)

View File

@@ -0,0 +1,11 @@
package config
var standalone bool
func SetStandalone() {
standalone = true
}
func Standalone() bool {
return standalone
}

View File

@@ -0,0 +1,44 @@
package config
import (
"os"
"path/filepath"
"strings"
"github.com/mitchellh/mapstructure"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/utils/runtimeenv"
"github.com/spf13/viper"
)
func Load(configDirectory string, configFileName string, envPrefix string, config any) error {
if runtimeenv.RuntimeEnvironment() == KUBERNETES {
mountPath := os.Getenv(MountConfigFilePath)
if mountPath == "" {
return errs.ErrArgs.WrapMsg(MountConfigFilePath + " env is empty")
}
return loadConfig(filepath.Join(mountPath, configFileName), envPrefix, config)
}
return loadConfig(filepath.Join(configDirectory, configFileName), envPrefix, config)
}
func loadConfig(path string, envPrefix string, config any) error {
v := viper.New()
v.SetConfigFile(path)
v.SetEnvPrefix(envPrefix)
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
if err := v.ReadInConfig(); err != nil {
return errs.WrapMsg(err, "failed to read config file", "path", path, "envPrefix", envPrefix)
}
if err := v.Unmarshal(config, func(config *mapstructure.DecoderConfig) {
config.TagName = StructTagName
}); err != nil {
return errs.WrapMsg(err, "failed to unmarshal config", "path", path, "envPrefix", envPrefix)
}
return nil
}

View File

@@ -0,0 +1,93 @@
package config
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLoadLogConfig(t *testing.T) {
var log Log
os.Setenv("IMENV_LOG_REMAINLOGLEVEL", "5")
err := Load("../../../config/", "log.yml", "IMENV_LOG", &log)
assert.Nil(t, err)
t.Log(log.RemainLogLevel)
// assert.Equal(t, "../../../../logs/", log.StorageLocation)
}
func TestLoadMongoConfig(t *testing.T) {
var mongo Mongo
// os.Setenv("DEPLOYMENT_TYPE", "kubernetes")
os.Setenv("IMENV_MONGODB_PASSWORD", "openIM1231231")
// os.Setenv("IMENV_MONGODB_URI", "openIM123")
// os.Setenv("IMENV_MONGODB_USERNAME", "openIM123")
err := Load("../../../config/", "mongodb.yml", "IMENV_MONGODB", &mongo)
// err := LoadApiConfig("../../../config/mongodb.yml", "IMENV_MONGODB", &mongo)
assert.Nil(t, err)
t.Log(mongo.Password)
// assert.Equal(t, "openIM123", mongo.Password)
t.Log(os.Getenv("IMENV_MONGODB_PASSWORD"))
t.Log(mongo)
// //export IMENV_OPENIM_RPC_USER_RPC_LISTENIP="0.0.0.0"
// assert.Equal(t, "0.0.0.0", user.RPC.ListenIP)
// //export IMENV_OPENIM_RPC_USER_RPC_PORTS="10110,10111,10112"
// assert.Equal(t, []int{10110, 10111, 10112}, user.RPC.Ports)
}
func TestLoadMinioConfig(t *testing.T) {
var storageConfig Minio
err := Load("../../../config/minio.yml", "IMENV_MINIO", "", &storageConfig)
assert.Nil(t, err)
assert.Equal(t, "openim", storageConfig.Bucket)
}
func TestLoadWebhooksConfig(t *testing.T) {
var webhooks Webhooks
err := Load("../../../config/webhooks.yml", "IMENV_WEBHOOKS", "", &webhooks)
assert.Nil(t, err)
assert.Equal(t, 5, webhooks.BeforeAddBlack.Timeout)
}
func TestLoadOpenIMRpcUserConfig(t *testing.T) {
var user User
err := Load("../../../config/openim-rpc-user.yml", "IMENV_OPENIM_RPC_USER", "", &user)
assert.Nil(t, err)
//export IMENV_OPENIM_RPC_USER_RPC_LISTENIP="0.0.0.0"
assert.Equal(t, "0.0.0.0", user.RPC.ListenIP)
//export IMENV_OPENIM_RPC_USER_RPC_PORTS="10110,10111,10112"
assert.Equal(t, []int{10110, 10111, 10112}, user.RPC.Ports)
}
func TestLoadNotificationConfig(t *testing.T) {
var noti Notification
err := Load("../../../config/notification.yml", "IMENV_NOTIFICATION", "", &noti)
assert.Nil(t, err)
assert.Equal(t, "Your friend's profile has been changed", noti.FriendRemarkSet.OfflinePush.Title)
}
func TestLoadOpenIMThirdConfig(t *testing.T) {
var third Third
err := Load("../../../config/openim-rpc-third.yml", "IMENV_OPENIM_RPC_THIRD", "", &third)
assert.Nil(t, err)
assert.Equal(t, "enabled", third.Object.Enable)
assert.Equal(t, "https://oss-cn-chengdu.aliyuncs.com", third.Object.Oss.Endpoint)
assert.Equal(t, "my_bucket_name", third.Object.Oss.Bucket)
assert.Equal(t, "https://my_bucket_name.oss-cn-chengdu.aliyuncs.com", third.Object.Oss.BucketURL)
assert.Equal(t, "AKID1234567890", third.Object.Oss.AccessKeyID)
assert.Equal(t, "abc123xyz789", third.Object.Oss.AccessKeySecret)
assert.Equal(t, "session_token_value", third.Object.Oss.SessionToken) // Uncomment if session token is needed
assert.Equal(t, true, third.Object.Oss.PublicRead)
// Environment: IMENV_OPENIM_RPC_THIRD_OBJECT_ENABLE=enabled;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_ENDPOINT=https://oss-cn-chengdu.aliyuncs.com;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_BUCKET=my_bucket_name;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_BUCKETURL=https://my_bucket_name.oss-cn-chengdu.aliyuncs.com;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_ACCESSKEYID=AKID1234567890;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_ACCESSKEYSECRET=abc123xyz789;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_SESSIONTOKEN=session_token_value;IMENV_OPENIM_RPC_THIRD_OBJECT_OSS_PUBLICREAD=true
}
func TestTransferConfig(t *testing.T) {
var tran MsgTransfer
err := Load("../../../config/openim-msgtransfer.yml", "IMENV_OPENIM-MSGTRANSFER", "", &tran)
assert.Nil(t, err)
assert.Equal(t, true, tran.Prometheus.Enable)
assert.Equal(t, true, tran.Prometheus.AutoSetPorts)
}

107
pkg/common/config/parse.go Normal file
View File

@@ -0,0 +1,107 @@
// 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.
package config
import (
"os"
"path/filepath"
"gopkg.in/yaml.v3"
"git.imall.cloud/openim/open-im-server-deploy/pkg/msgprocessor"
"git.imall.cloud/openim/protocol/constant"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/field"
)
const (
DefaultFolderPath = "../config/"
)
// return absolude path join ../config/, this is k8s container config path.
func GetDefaultConfigPath() (string, error) {
executablePath, err := os.Executable()
if err != nil {
return "", errs.WrapMsg(err, "failed to get executable path")
}
configPath, err := field.OutDir(filepath.Join(filepath.Dir(executablePath), "../config/"))
if err != nil {
return "", errs.WrapMsg(err, "failed to get output directory", "outDir", filepath.Join(filepath.Dir(executablePath), "../config/"))
}
return configPath, nil
}
// getProjectRoot returns the absolute path of the project root directory.
func GetProjectRoot() (string, error) {
executablePath, err := os.Executable()
if err != nil {
return "", errs.Wrap(err)
}
projectRoot, err := field.OutDir(filepath.Join(filepath.Dir(executablePath), "../../../../.."))
if err != nil {
return "", errs.Wrap(err)
}
return projectRoot, nil
}
func GetOptionsByNotification(cfg NotificationConfig, sendMessage *bool) msgprocessor.Options {
opts := msgprocessor.NewOptions()
if sendMessage != nil {
cfg.IsSendMsg = *sendMessage
}
if cfg.IsSendMsg {
opts = msgprocessor.WithOptions(opts, msgprocessor.WithUnreadCount(true))
}
if cfg.OfflinePush.Enable {
opts = msgprocessor.WithOptions(opts, msgprocessor.WithOfflinePush(true))
}
switch cfg.ReliabilityLevel {
case constant.UnreliableNotification:
case constant.ReliableNotificationNoMsg:
opts = msgprocessor.WithOptions(opts, msgprocessor.WithHistory(true), msgprocessor.WithPersistent())
}
opts = msgprocessor.WithOptions(opts, msgprocessor.WithSendMsg(cfg.IsSendMsg))
return opts
}
// initConfig loads configuration from a specified path into the provided config structure.
// 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.
func initConfig(config any, configName, configFolderPath string) error {
configFolderPath = filepath.Join(configFolderPath, configName)
_, err := os.Stat(configFolderPath)
if err != nil {
if !os.IsNotExist(err) {
return errs.WrapMsg(err, "stat config path error", "config Folder Path", configFolderPath)
}
path, err := GetProjectRoot()
if err != nil {
return err
}
configFolderPath = filepath.Join(path, "config", configName)
}
data, err := os.ReadFile(configFolderPath)
if err != nil {
return errs.WrapMsg(err, "read file error", "config Folder Path", configFolderPath)
}
if err = yaml.Unmarshal(data, config); err != nil {
return errs.WrapMsg(err, "unmarshal yaml error", "config Folder Path", configFolderPath)
}
return nil
}