sipd-transaksi-belanja/main.go
2025-09-16 08:37:42 +07:00

232 lines
6.3 KiB
Go

package main
import (
"context"
"database/sql"
"fmt"
"kemendagri/sipd/services/transaksi-belanja-sipd/controllers"
hdl "kemendagri/sipd/services/transaksi-belanja-sipd/handler"
"kemendagri/sipd/services/transaksi-belanja-sipd/handler/configs"
"kemendagri/sipd/services/transaksi-belanja-sipd/handler/http_util"
_deliveryMiddleware "kemendagri/sipd/services/transaksi-belanja-sipd/handler/middleware"
"kemendagri/sipd/services/transaksi-belanja-sipd/utils"
"log"
"os"
"strconv"
"strings"
"time"
swagDoc "kemendagri/sipd/services/transaksi-belanja-sipd/docs"
swagger "github.com/arsmn/fiber-swagger/v2"
"github.com/go-playground/validator/v10"
"github.com/gofiber/fiber/v2"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database"
"github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
"github.com/jackc/pgx/v5/pgxpool"
_ "github.com/lib/pq"
)
var db *sql.DB
var pgxConn *pgxpool.Pool
var driver database.Driver
var migration *migrate.Migrate
var vld *validator.Validate
var err error
var serverName, serverUrl, serverReadTimeout, alwOrg, dbConn, urlScheme, baseUrl, basePath string
func init() {
serverName = os.Getenv("SERVER_NAME")
if serverName == "" {
exitf("SERVER_NAME env is required")
}
serverUrl = os.Getenv("SERVER_URL")
if serverUrl == "" {
exitf("SERVER_URL env is required")
}
serverReadTimeout = os.Getenv("SERVER_READ_TIMEOUT")
if serverReadTimeout == "" {
exitf("SERVER_READ_TIMEOUT env is required")
}
alwOrg = os.Getenv("SIPD_CORS_WHITELISTS")
if alwOrg == "" {
exitf("SIPD_CORS_WHITELISTS config is required")
}
// Databse Env
dbConn = os.Getenv("DB_CONN")
if dbConn == "" {
exitf("DB_CONN config is required")
}
urlScheme = os.Getenv("URL_SCHEME")
if urlScheme == "" {
exitf("URL_SCHEME config is required")
}
baseUrl = os.Getenv("BASE_URL")
if baseUrl == "" {
exitf("BASE_URL config is required")
}
basePath = os.Getenv("BASE_PATH")
if basePath == "" {
exitf("BASE_PATH config is required")
}
}
func databaseMigration() {
db, err = sql.Open("postgres", dbConn) //sesuaikan saat migrasi
if err != nil {
exitf("Db open error: %v\n", err)
}
driver, err = postgres.WithInstance(db, &postgres.Config{})
if err != nil {
_ = db.Close()
exitf("Db postgres driven error: %v\n", err)
}
migration, err = migrate.NewWithDatabaseInstance("file://migrations", "postgres", driver)
if err != nil {
_ = db.Close()
exitf("Unable to initiate migration: %v\n", err)
}
err = migration.Up() // or m.Step(2) if you want to explicitly set the number of migrations to run
if err != nil {
log.Println(fmt.Sprintf("Migration error: %s", err.Error()))
}
err = db.Close()
if err != nil {
log.Println(fmt.Sprintf("Db close error: %s", err.Error()))
}
}
func dbConnection() {
var maxConnLifetime, maxConnIdleTime time.Duration
maxConnLifetime = 5 * time.Minute
maxConnIdleTime = 2 * time.Minute
var cfg *pgxpool.Config
cfg, err = pgxpool.ParseConfig(dbConn)
if err != nil {
exitf("Unable to create db pool config sipd_anggaran %v\n", err)
}
// cfg.MaxConns = 1000 // Maximum total connections in the pool
cfg.MaxConnLifetime = maxConnLifetime // Maximum lifetime of a connection
cfg.MaxConnIdleTime = maxConnIdleTime // Maximum time a connection can be idle
pgxConn, err = pgxpool.NewWithConfig(context.Background(), cfg)
if err != nil {
exitf("Unable to connect to database sipd_anggaran %v\n", err)
}
}
// @title SIPD Service Transaksi Belanja
// @version 1.0
// @description SIPD Service Transaksi Belanja Rest API.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.email lifelinejar@mail.com
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
// @BasePath /
func main() {
// migrasi database
// databaseMigration()
// Pgx Pool Connection
dbConnection()
defer func() {
pgxConn.Close()
}()
// End Pgx Pool Connection
// Define a validator
vld = utils.NewValidator()
// Define Fiber config.
config := configs.FiberConfig()
app := fiber.New(config)
middL := _deliveryMiddleware.InitMiddleware(app)
//app.Use(middL.RateLimiter())
app.Use(middL.CORS())
app.Use(middL.LOGGER())
app.Use(func(c *fiber.Ctx) error { // Middleware to check for whitelisted domains
if alwOrg == "*" {
// Continue to the next middleware/handler
return c.Next()
}
// Use "X-Forwarded-Host" to simulate the Host header in Postman
origin := c.Get("Origin")
// log.Println("Origin: ", origin)
alwOrgArr := strings.Split(alwOrg, ",")
// log.Println("alwOrgArr: ", alwOrgArr)
var originMatch bool
for _, alo := range alwOrgArr {
if origin == alo {
originMatch = true
break
} else {
/*host := c.Hostname()
// log.Println("Host: ", host)
if "https://"+host == alo || "http://"+host == alo {
originMatch = true
break
}*/
}
}
if !originMatch {
log.Println("alwOrgArr: ", alwOrgArr)
log.Println("Origin: ", origin)
return c.Status(fiber.StatusForbidden).SendString("403 - MSTDT: origin not allowed")
}
// Continue to the next middleware/handler
return c.Next()
})
// Swagger handler
// app.Get("/swagger/*", swagger.HandlerDefault)
swagDoc.SwaggerInfo.Host = baseUrl
swagDoc.SwaggerInfo.BasePath = basePath
app.Get("/swagger/*", swagger.New(swagger.Config{
URL: urlScheme + baseUrl + basePath + "swagger/doc.json", // default search box
}))
serverReadTimeoutInt, err := strconv.Atoi(serverReadTimeout)
if err != nil {
exitf("Failed casting timeout context: ", err)
}
timeoutContext := time.Duration(serverReadTimeoutInt) * time.Second
// welcome router
welcomeController := controllers.NewWelcomeController(pgxConn, timeoutContext)
hdl.NewWelcomeHandler(app, vld, welcomeController)
// end welcome router
// kecamatan router
// kecamatanController := controllers.NewKecamatanController(pgxConn, timeoutContext)
// hdl.NewKecamatanHandler(app, vld, kecamatanController)
// end kecamatan router
http_util.StartServer(app)
}
func exitf(s string, args ...interface{}) {
errorf(s, args...)
os.Exit(1)
}
func errorf(s string, args ...interface{}) {
fmt.Fprintf(os.Stderr, s+"\n", args...)
}