diff --git a/internal/push/offlinepush/fcm/push.go b/internal/push/offlinepush/fcm/push.go index 8145d4c17..1bbba4bd0 100644 --- a/internal/push/offlinepush/fcm/push.go +++ b/internal/push/offlinepush/fcm/push.go @@ -16,6 +16,7 @@ package fcm import ( "context" + "fmt" "path/filepath" firebase "firebase.google.com/go" @@ -39,23 +40,36 @@ type Fcm struct { cache cache.MsgModel } -func NewClient(cache cache.MsgModel) *Fcm { - projectRoot := config.GetProjectRoot() - credentialsFilePath := filepath.Join(projectRoot, "config", config.Config.Push.Fcm.ServiceAccount) - opt := option.WithCredentialsFile(credentialsFilePath) - fcmApp, err := firebase.NewApp(context.Background(), nil, opt) - if err != nil { - return nil - } +// NewClient initializes a new FCM client using the Firebase Admin SDK. +// It requires the FCM service account credentials file located within the project's configuration directory. +// The function returns an Fcm pointer on success, or nil and an error if initialization fails. +func NewClient(cache cache.MsgModel) (*Fcm, error) { + // Attempt to get the project root directory. + projectRoot, err := config.GetProjectRoot() + if err != nil { + return nil, fmt.Errorf("failed to get project root: %w", err) + } - ctx := context.Background() - fcmMsgClient, err := fcmApp.Messaging(ctx) - if err != nil { - return nil - } - return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache} + credentialsFilePath := filepath.Join(projectRoot, "config", config.Config.Push.Fcm.ServiceAccount) + opt := option.WithCredentialsFile(credentialsFilePath) + + // Initialize the Firebase app with the specified service account credentials. + fcmApp, err := firebase.NewApp(context.Background(), nil, opt) + if err != nil { + return nil, fmt.Errorf("failed to initialize Firebase app: %w", err) + } + + // Obtain the messaging client from the Firebase app. + ctx := context.Background() + fcmMsgClient, err := fcmApp.Messaging(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get Firebase messaging client: %w", err) + } + + return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}, nil } + func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error { // accounts->registrationToken allTokens := make(map[string][]string, 0) diff --git a/internal/push/push_to_client.go b/internal/push/push_to_client.go index 5fce34e83..9869da5e5 100644 --- a/internal/push/push_to_client.go +++ b/internal/push/push_to_client.go @@ -82,7 +82,7 @@ func NewOfflinePusher(cache cache.MsgModel) offlinepush.OfflinePusher { case "getui": offlinePusher = getui.NewClient(cache) case "fcm": - offlinePusher = fcm.NewClient(cache) + offlinePusher, _ = fcm.NewClient(cache) case "jpush": offlinePusher = jpush.NewClient() default: diff --git a/pkg/common/cmd/api.go b/pkg/common/cmd/api.go index 48c8863c1..64251a422 100644 --- a/pkg/common/cmd/api.go +++ b/pkg/common/cmd/api.go @@ -32,17 +32,29 @@ func NewApiCmd() *ApiCmd { return ret } +// AddApi configures the API command to run with specified ports for the API and Prometheus monitoring. +// It ensures error handling for port retrieval and only proceeds if both port numbers are successfully obtained. func (a *ApiCmd) AddApi(f func(port int, promPort int) error) { a.Command.RunE = func(cmd *cobra.Command, args []string) error { - return f(a.getPortFlag(cmd), a.getPrometheusPortFlag(cmd)) + port, err := a.getPortFlag(cmd) + if err != nil { + return err + } + + promPort, err := a.getPrometheusPortFlag(cmd) + if err != nil { + return err + } + + return f(port, promPort) } } -func (a *ApiCmd) GetPortFromConfig(portType string) (int, error) { +func (a *ApiCmd) GetPortFromConfig(portType string) (int,) { if portType == constant.FlagPort { - return config2.Config.Api.OpenImApiPort[0], nil + return config2.Config.Api.OpenImApiPort[0] } else if portType == constant.FlagPrometheusPort { - return config2.Config.Prometheus.ApiPrometheusPort[0], nil + return config2.Config.Prometheus.ApiPrometheusPort[0] } - return 0, nil + return 0 } diff --git a/pkg/common/cmd/msg_gateway_test.go b/pkg/common/cmd/msg_gateway_test.go index c0ea2b057..106ad74ec 100644 --- a/pkg/common/cmd/msg_gateway_test.go +++ b/pkg/common/cmd/msg_gateway_test.go @@ -44,7 +44,7 @@ func TestMsgGatewayCmd_GetPortFromConfig(t *testing.T) { } for _, tt := range tests { t.Run(tt.portType, func(t *testing.T) { - got := msgGatewayCmd.GetPortFromConfig(tt.portType) + got, _ := msgGatewayCmd.GetPortFromConfig(tt.portType) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/common/config/parse.go b/pkg/common/config/parse.go index 5314ec7a9..2233f6d0d 100644 --- a/pkg/common/config/parse.go +++ b/pkg/common/config/parse.go @@ -54,6 +54,23 @@ func GetDefaultConfigPath() (string, error) { return configPath, nil } +// GetProjectRoot returns the absolute path of the project root directory by navigating up from the directory +// containing the executable. It provides a detailed error if the path cannot be determined. +func GetProjectRoot() (string, error) { + executablePath, err := os.Executable() + if err != nil { + return "", errs.Wrap(err, "failed to retrieve executable path") + } + + // Attempt to compute the project root by navigating up from the executable's directory + projectRoot, err := genutil.OutDir(filepath.Join(filepath.Dir(executablePath), "../../../../..")) + if err != nil { + return "", errs.Wrap(err, "failed to determine project root directory") + } + + return projectRoot, nil +} + func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options { opts := msgprocessor.NewOptions() @@ -73,25 +90,36 @@ func GetOptionsByNotification(cfg NotificationConf) msgprocessor.Options { 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) + configFilePath := filepath.Join(configFolderPath, configName) + _, err := os.Stat(configFilePath) if err != nil { if !os.IsNotExist(err) { - return errs.Wrap(err, "stat config path error") + return errs.Wrap(err, fmt.Sprintf("failed to check existence of config file at path: %s", configFilePath)) } - configFolderPath = filepath.Join(GetProjectRoot(), "config", configName) - fmt.Println("flag's path,enviment's path,default path all is not exist,using project path:", configFolderPath) + projectRoot, err := GetProjectRoot() + if err != nil { + return err + } + configFilePath = filepath.Join(projectRoot, "config", configName) + fmt.Printf("Configuration file not found at specified path. Falling back to project path: %s\n", configFilePath) } - data, err := os.ReadFile(configFolderPath) + + data, err := os.ReadFile(configFilePath) if err != nil { - return errs.Wrap(err, "read file error") + // Wrap and return the error if reading the configuration file fails. + return errs.Wrap(err, fmt.Sprintf("failed to read configuration file at path: %s", configFilePath)) } + if err = yaml.Unmarshal(data, config); err != nil { - return errs.Wrap(err, "unmarshal yaml error") + // Wrap and return the error if unmarshalling the YAML configuration fails. + return errs.Wrap(err, "failed to unmarshal YAML configuration") } - fmt.Println("The path of the configuration file to start the process:", configFolderPath) + fmt.Printf("Configuration file loaded successfully from path: %s\n", configFilePath) return nil } @@ -107,7 +135,6 @@ func InitConfig(configFolderPath string) error { var err error configFolderPath, err = GetDefaultConfigPath() if err != nil { - // Wrap and return the error if getting the default config path fails return err } } diff --git a/pkg/common/convert/user.go b/pkg/common/convert/user.go index 62f80e458..4b08554df 100644 --- a/pkg/common/convert/user.go +++ b/pkg/common/convert/user.go @@ -17,7 +17,7 @@ package convert import ( "time" - "github.com/OpenIMSDK/protocol/sdkws" +"github.com/OpenIMSDK/protocol/sdkws" relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) diff --git a/pkg/common/db/cache/black.go b/pkg/common/db/cache/black.go index d1abe945c..48bc3c285 100644 --- a/pkg/common/db/cache/black.go +++ b/pkg/common/db/cache/black.go @@ -46,11 +46,7 @@ type BlackCacheRedis struct { blackDB relationtb.BlackModelInterface } -func NewBlackCacheRedis( - rdb redis.UniversalClient, - blackDB relationtb.BlackModelInterface, - options rockscache.Options, -) BlackCache { +func NewBlackCacheRedis(rdb redis.UniversalClient, blackDB relationtb.BlackModelInterface, options rockscache.Options) BlackCache { rcClient := rockscache.NewClient(rdb, options) return &BlackCacheRedis{ diff --git a/pkg/common/db/cache/msg.go b/pkg/common/db/cache/msg.go index 9a4844e26..5cef509ed 100644 --- a/pkg/common/db/cache/msg.go +++ b/pkg/common/db/cache/msg.go @@ -24,8 +24,6 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" - "github.com/OpenIMSDK/tools/errs" - "github.com/gogo/protobuf/jsonpb" "github.com/OpenIMSDK/protocol/constant" @@ -443,7 +441,7 @@ func (c *msgCache) PipeSetMessageToCache(ctx context.Context, conversationID str results, err := pipe.Exec(ctx) if err != nil { - return 0, errs.Warp(err) + return 0, errs.Wrap(err) } for _, res := range results { diff --git a/pkg/rpcclient/auth.go b/pkg/rpcclient/auth.go index 0ee021de1..810b7ae93 100644 --- a/pkg/rpcclient/auth.go +++ b/pkg/rpcclient/auth.go @@ -23,12 +23,13 @@ import ( "github.com/OpenIMSDK/tools/discoveryregistry" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil" ) func NewAuth(discov discoveryregistry.SvcDiscoveryRegistry) *Auth { conn, err := discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImAuthName) if err != nil { - panic(err) + util.ExitWithError(err) } client := auth.NewAuthClient(conn) return &Auth{discov: discov, conn: conn, Client: client} diff --git a/pkg/rpcclient/conversation.go b/pkg/rpcclient/conversation.go index 6b5b3ee87..9afa45004 100644 --- a/pkg/rpcclient/conversation.go +++ b/pkg/rpcclient/conversation.go @@ -116,11 +116,7 @@ func (c *ConversationRpcClient) GetConversationsByConversationID(ctx context.Con return resp.Conversations, nil } -func (c *ConversationRpcClient) GetConversations( - ctx context.Context, - ownerUserID string, - conversationIDs []string, -) ([]*pbconversation.Conversation, error) { +func (c *ConversationRpcClient) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*pbconversation.Conversation, error) { if len(conversationIDs) == 0 { return nil, nil }