Skip to content

Commit

Permalink
Merge pull request #23 from DoWithLogic/feat/new-version
Browse files Browse the repository at this point in the history
enhancement this repository
  • Loading branch information
martinyonatann committed May 8, 2024
2 parents 0c5c35b + 2ab9549 commit 25e379d
Show file tree
Hide file tree
Showing 58 changed files with 2,358 additions and 1,243 deletions.
Empty file added .coverage/.keep
Empty file.
8 changes: 6 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
config/config-local.yaml
vendor/

vendor/
# we want to ignore files under this directory (ends with /*)
.coverage/*

# we want to keep track of this .keep files (starts with !)
!.keep
44 changes: 38 additions & 6 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,53 @@ package main

import (
"context"
"os"
"time"

"github.com/DoWithLogic/golang-clean-architecture/config"
"github.com/DoWithLogic/golang-clean-architecture/internal/app"
"github.com/DoWithLogic/golang-clean-architecture/pkg/observability"
"github.com/labstack/gommon/log"
)

func main() {
env := os.Getenv("env")
if env == "" {
env = "local"
// Load the application configuration from the specified directory.
cfg, err := config.LoadConfig("config")
if err != nil {
// If an error occurs while loading the configuration, panic with the error.
panic(err)
}

cfg, err := config.LoadConfig(env)
// Set the time zone to the specified value from the configuration.
_, err = time.LoadLocation(cfg.Server.TimeZone)
if err != nil {
panic(err)
// If an error occurs while setting the time zone, log the error and exit the function.
log.Error("Error on setting the time zone: ", err)
return
}

// Initialize observability components if observability is enabled in the configuration.
if cfg.Observability.Enable {
// Initialize the tracer provider for distributed tracing.
tracer, err := observability.InitTracerProvider(cfg)
if err != nil {
log.Warn("Failed to initialize tracer: ", err)
}

// Initialize the meter provider for metrics collection.
meter, err := observability.InitMeterProvider(cfg)
if err != nil {
log.Warn("Failed to initialize meter: ", err)
}

// Ensure that the tracer and meter are shut down when the main function exits.
defer func() {
if tracer != nil {
tracer.Shutdown(context.Background())
}
if meter != nil {
meter.Shutdown(context.Background())
}
}()
}

app.NewApp(context.Background(), cfg).Run()
Expand Down
26 changes: 26 additions & 0 deletions config/config-local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
App:
Name: "golang-clean-architecture"
Version: "v0.0.1"
Scheme: "http"
Host: "localhost:3002"
Environment: local #local,development,staging,production

Server:
Port: "9090"
Debug: true
TimeZone: "Asia/Jakarta"


Database:
Host: 127.0.0.1
Port: 3306
Name: users
User: root
Password: pwd

Authentication:
Key: DoWithLogic!@#

Observability:
Enable: false
Mode: "otlp/http"
21 changes: 0 additions & 21 deletions config/config-local.yaml.example

This file was deleted.

99 changes: 80 additions & 19 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
package config

import (
"errors"
"fmt"
"time"
"log"
"strings"

"github.com/spf13/viper"
)

type (
Config struct {
Database DatabaseConfig
App AppConfig
Server ServerConfig
Database DatabaseConfig
Authentication AuthenticationConfig
Observability ObservabilityConfig
JWT JWTConfig
}

// AppConfig holds the configuration related to the application settings.
AppConfig struct {
Name string
Version string
Schema string
Host string
Environment string
}

// ServerConfig holds the configuration for the server settings.
ServerConfig struct {
Port string // The port on which the server will listen.
Debug bool // Indicates if debug mode is enabled.
TimeZone string // The time zone setting for the server.
}

// DatabaseConfig holds the configuration for the database connection.
DatabaseConfig struct {
Host string
Port int
Expand All @@ -22,37 +44,76 @@ type (
Password string
}

ServerConfig struct {
Name string
Version string
RPCPort string
RESTPort string
Debug bool
Environment string
ReadTimeout time.Duration
WriteTimeout time.Duration
AuthenticationConfig struct {
Key string
}

AuthenticationConfig struct {
Key string
SecretKey string
SaltKey string
// ObservabilityConfig holds the configuration for observability settings.
ObservabilityConfig struct {
Enable bool // Indicates if observability is enabled.
Mode string // Specifies the observability mode.
}

JWTConfig struct {
Key string
Expired int
Label string
}
)

func LoadConfig(env string) (Config, error) {
viper.SetConfigFile(fmt.Sprintf("config/config-%s.yaml", env))
// LoadConfig loads the configuration from the specified filename.
func LoadConfig(filename string) (Config, error) {
// Create a new Viper instance.
v := viper.New()

if err := viper.ReadInConfig(); err != nil {
// Set the configuration file name, path, and environment variable settings.
v.SetConfigName(fmt.Sprintf("config/%s", filename))
v.AddConfigPath(".")
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

// Read the configuration file.
if err := v.ReadInConfig(); err != nil {
fmt.Printf("Error reading config file: %v\n", err)
return Config{}, err
}

// Unmarshal the configuration into the Config struct.
var config Config
if err := viper.Unmarshal(&config); err != nil {
if err := v.Unmarshal(&config); err != nil {
fmt.Printf("Error unmarshaling config: %v\n", err)
return Config{}, err
}

return config, nil
}

// LoadConfigPath loads the configuration from the specified path.
func LoadConfigPath(path string) (Config, error) {
// Create a new Viper instance.
v := viper.New()

// Set the configuration file name, path, and environment variable settings.
v.SetConfigName(path)
v.AddConfigPath(".")
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

// Read the configuration file.
if err := v.ReadInConfig(); err != nil {
// Handle the case where the configuration file is not found.
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
return Config{}, errors.New("config file not found")
}
return Config{}, err
}

// Parse the configuration into the Config struct.
var c Config
if err := v.Unmarshal(&c); err != nil {
log.Printf("unable to decode into struct, %v", err)
return Config{}, err
}

return c, nil
}
26 changes: 26 additions & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
App:
Name: "golang-clean-architecture"
Version: "v0.0.1"
Scheme: "http"
Host: "localhost:3002"
Environment: local #local,development,staging,production

Server:
Port: "9090"
Debug: true
TimeZone: "Asia/Jakarta"


Database:
Host: 127.0.0.1
Port: 3306
Name: users
User: root
Password: pwd

Authentication:
Key: DoWithLogic!@#

Observability:
Enable: false
Mode: "otlp/http"
2 changes: 0 additions & 2 deletions database/mysql/migration/20230924142159_add_user_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ CREATE TABLE `users` (
`user_type` varchar(50) NOT NULL,
`is_active` tinyint(1) NOT NULL,
`created_at` timestamp NOT NULL,
`created_by` varchar(255) NOT NULL,
`updated_at` timestamp DEFAULT NULL,
`updated_by` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Expand Down
15 changes: 4 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,7 @@ services:
interval: 0.5s
timeout: 10s
retries: 10
golang-clean-architecture:
build:
context: .
dockerfile: Dockerfile # Specify the path to your Dockerfile
ports:
- 8080:8080
- 9090:9090
volumes:
- ./config/config-local.yaml:/app/config/config-local.yaml
depends_on:
- mysql-db
entrypoint:
sh -c "
echo 'CREATE DATABASE IF NOT EXISTS users;' > /docker-entrypoint-initdb.d/init.sql;
/usr/local/bin/docker-entrypoint.sh --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci"
Loading

0 comments on commit 25e379d

Please sign in to comment.