Skip to content

Commit

Permalink
feat: ✨ supporting Inbox and Outbox Pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdihadeli committed Nov 29, 2023
1 parent dfa600b commit dfa0d50
Show file tree
Hide file tree
Showing 46 changed files with 605 additions and 210 deletions.
26 changes: 15 additions & 11 deletions internal/pkg/config/config_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ func BindConfigKey[T any](
) (T, error) {
var configPath string

environment := environment.Environment("")
currentEnv := environment.Environment("")
if len(environments) > 0 {
environment = environments[0]
currentEnv = environments[0]
} else {
environment = constants.Dev
currentEnv = constants.Dev
}

cfg := typeMapper.GenericInstanceByT[T]()
Expand All @@ -41,7 +41,7 @@ func BindConfigKey[T any](

// https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d
// when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string
// load `config path` from environment variable or viper internal registry
// load `config path` from env variable or viper internal registry
configPathFromEnv := viper.GetString(constants.ConfigPath)

if configPathFromEnv != "" {
Expand All @@ -50,8 +50,11 @@ func BindConfigKey[T any](
// https://stackoverflow.com/questions/31873396/is-it-possible-to-get-the-current-root-of-package-structure-as-a-string-in-golan
// https://stackoverflow.com/questions/18537257/how-to-get-the-directory-of-the-currently-running-file
appRootPath := viper.GetString(constants.AppRootPath)
if appRootPath == "" {
appRootPath = environment.GetProjectRootWorkingDirectory()
}

d, err := searchForConfigFileDir(appRootPath, environment)
d, err := searchForConfigFileDir(appRootPath, currentEnv)
if err != nil {
return *new(T), err
}
Expand All @@ -60,7 +63,7 @@ func BindConfigKey[T any](
}

// https://github.com/spf13/viper/issues/390#issuecomment-718756752
viper.SetConfigName(fmt.Sprintf("config.%s", environment))
viper.SetConfigName(fmt.Sprintf("config.%s", currentEnv))
viper.AddConfigPath(configPath)
viper.SetConfigType(constants.Json)

Expand Down Expand Up @@ -104,7 +107,7 @@ func BindConfigKey[T any](
// error: An error indicating any issues encountered during the search.
func searchForConfigFileDir(
rootDir string,
environment environment.Environment,
env environment.Environment,
) (string, error) {
var result string

Expand All @@ -116,23 +119,24 @@ func searchForConfigFileDir(
return err
}

// Check if the file is named "config.%s.json" (replace %s with the environment)
// Check if the file is named "config.%s.json" (replace %s with the env)
if !info.IsDir() &&
strings.EqualFold(
info.Name(),
fmt.Sprintf("config.%s.json", environment),
fmt.Sprintf("config.%s.json", env),
) ||
strings.EqualFold(
info.Name(),
fmt.Sprintf("config.%s.yaml", environment),
fmt.Sprintf("config.%s.yaml", env),
) ||
strings.EqualFold(
info.Name(),
fmt.Sprintf("config.%s.yml", environment),
fmt.Sprintf("config.%s.yml", env),
) {
// Get the directory name containing the config file
dir := filepath.Dir(path)
result = dir

return filepath.SkipDir // Skip further traversal
}

Expand Down
77 changes: 2 additions & 75 deletions internal/pkg/config/environment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"log"
"os"
"path/filepath"
"strings"
"syscall"

"github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants"
Expand Down Expand Up @@ -42,7 +41,7 @@ func ConfigAppEnv(environments ...Environment) Environment {

setRootWorkingDirectoryEnvironment()

fixTestEnvironmentWorkingDirectory()
FixProjectRootWorkingDirectoryPath()

manualEnv := os.Getenv(constants.AppEnv)

Expand Down Expand Up @@ -108,80 +107,8 @@ func loadEnvFilesRecursive() error {
}

func setRootWorkingDirectoryEnvironment() {
var rootWorkingDirectory string
// https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d
// when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string
// viper will get it from `os env` or a .env file
pn := viper.GetString(constants.PROJECT_NAME_ENV)
if pn != "" {
rootWorkingDirectory = getRootDirectoryFromProjectName(pn)
} else {
wd, _ := os.Getwd()
dir, err := searchRootDirectory(wd)
if err != nil {
log.Fatal(err)
}
rootWorkingDirectory = dir
}

absoluteRootWorkingDirectory, _ := filepath.Abs(rootWorkingDirectory)
absoluteRootWorkingDirectory := GetProjectRootWorkingDirectory()

// when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string
viper.Set(constants.AppRootPath, absoluteRootWorkingDirectory)
}

func fixTestEnvironmentWorkingDirectory() {
currentWD, _ := os.Getwd()
log.Printf("Current test working directory is: %s", currentWD)

rootDir := viper.GetString(constants.AppRootPath)
if rootDir != "" {
_ = os.Chdir(rootDir)

newWD, _ := os.Getwd()
log.Printf("New test working directory is: %s", newWD)
}
}

func getRootDirectoryFromProjectName(pn string) string {
// set root working directory of our app in the viper
// https://stackoverflow.com/a/47785436/581476
wd, _ := os.Getwd()

for !strings.HasSuffix(wd, pn) {
wd = filepath.Dir(wd)
}

return wd
}

func searchRootDirectory(
dir string,
) (string, error) {
// List files and directories in the current directory
files, err := os.ReadDir(dir)
if err != nil {
return "", errors.WrapIf(err, "Error reading directory")
}

for _, file := range files {
if !file.IsDir() {
fileName := file.Name()
if strings.EqualFold(
fileName,
"go.mod",
) {
return dir, nil
}
}
}

// If no config file found in this directory, recursively search its parent
parentDir := filepath.Dir(dir)
if parentDir == dir {
// We've reached the root directory, and no go.mod file was found
return "", errors.WrapIf(err, "No go.mod file found")
}

return searchRootDirectory(parentDir)
}
90 changes: 90 additions & 0 deletions internal/pkg/config/environment/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package environment

import (
"log"
"os"
"path/filepath"
"strings"

"github.com/mehdihadeli/go-ecommerce-microservices/internal/pkg/constants"

"emperror.dev/errors"
"github.com/spf13/viper"
)

func FixProjectRootWorkingDirectoryPath() {
currentWD, _ := os.Getwd()
log.Printf("Current working directory is: `%s`", currentWD)

rootDir := GetProjectRootWorkingDirectory()
// change working directory
_ = os.Chdir(rootDir)
newWD, _ := os.Getwd()

log.Printf("New fixed working directory is: `%s`", newWD)
}

func GetProjectRootWorkingDirectory() string {
var rootWorkingDirectory string
// https://articles.wesionary.team/environment-variable-configuration-in-your-golang-project-using-viper-4e8289ef664d
// when we `Set` a viper with string value, we should get it from viper with `viper.GetString`, elsewhere we get empty string
// viper will get it from `os env` or a .env file
pn := viper.GetString(constants.PROJECT_NAME_ENV)
if pn != "" {
rootWorkingDirectory = getProjectRootDirectoryFromProjectName(pn)
} else {
wd, _ := os.Getwd()
dir, err := searchRootDirectory(wd)
if err != nil {
log.Fatal(err)
}
rootWorkingDirectory = dir
}

absoluteRootWorkingDirectory, _ := filepath.Abs(rootWorkingDirectory)

return absoluteRootWorkingDirectory
}

func getProjectRootDirectoryFromProjectName(pn string) string {
// set root working directory of our app in the viper
// https://stackoverflow.com/a/47785436/581476
wd, _ := os.Getwd()

for !strings.HasSuffix(wd, pn) {
wd = filepath.Dir(wd)
}

return wd
}

func searchRootDirectory(
dir string,
) (string, error) {
// List files and directories in the current directory
files, err := os.ReadDir(dir)
if err != nil {
return "", errors.WrapIf(err, "Error reading directory")
}

for _, file := range files {
if !file.IsDir() {
fileName := file.Name()
if strings.EqualFold(
fileName,
"go.mod",
) {
return dir, nil
}
}
}

// If no config file found in this directory, recursively search its parent
parentDir := filepath.Dir(dir)
if parentDir == dir {
// We've reached the root directory, and no go.mod file was found
return "", errors.WrapIf(err, "No go.mod file found")
}

return searchRootDirectory(parentDir)
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package persistmessage

import "context"
import (
"context"

uuid "github.com/satori/go.uuid"
)

type MessagePersistenceRepository interface {
Add(ctx context.Context, storeMessage *StoreMessage) error
Update(ctx context.Context, storeMessage *StoreMessage) error
ChangeState(
ctx context.Context,
messageID string,
messageID uuid.UUID,
status MessageStatus,
) error
GetAll(ctx context.Context) ([]*StoreMessage, error)
GetAllActive(ctx context.Context) ([]*StoreMessage, error)
GetByFilter(
ctx context.Context,
predicate func(*StoreMessage) bool,
) ([]*StoreMessage, error)
GetById(ctx context.Context, id string) (*StoreMessage, error)
GetById(ctx context.Context, id uuid.UUID) (*StoreMessage, error)
Remove(ctx context.Context, storeMessage *StoreMessage) (bool, error)
CleanupMessages()
CleanupMessages(ctx context.Context) error
}
14 changes: 11 additions & 3 deletions internal/pkg/core/messaging/persistmessage/store_message.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package persistmessage

import "time"
import (
"time"

uuid "github.com/satori/go.uuid"
)

type MessageDeliveryType int

Expand All @@ -18,7 +22,7 @@ const (
)

type StoreMessage struct {
ID string
ID uuid.UUID `gorm:"primaryKey"`
DataType string
Data string
Created time.Time
Expand All @@ -28,7 +32,7 @@ type StoreMessage struct {
}

func NewStoreMessage(
id string,
id uuid.UUID,
dataType string,
data string,
deliveryType MessageDeliveryType,
Expand All @@ -51,3 +55,7 @@ func (sm *StoreMessage) ChangeState(messageStatus MessageStatus) {
func (sm *StoreMessage) IncreaseRetry() {
sm.RetryCount++
}

func (sm *StoreMessage) TableName() string {
return "store_messages"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"database/sql"
Expand Down Expand Up @@ -66,6 +66,7 @@ func createInMemoryDB() (*gorm.DB, error) {
&gorm.Config{
Logger: gromlog.NewGormCustomLogger(defaultlogger.GetLogger()),
})

return db, err
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"testing"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package postgresGorm
package postgresgorm

import (
"context"
Expand Down
Loading

0 comments on commit dfa0d50

Please sign in to comment.