-
Notifications
You must be signed in to change notification settings - Fork 166
Added thunder oauth & flow libraries #1871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop-go
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| // Command esignet is the esignet HTTP service entrypoint. | ||
| package main | ||
|
|
||
| import ( | ||
|
|
@@ -6,22 +7,29 @@ import ( | |
| "log/slog" | ||
| "os" | ||
| "os/signal" | ||
| "strings" | ||
| "syscall" | ||
|
|
||
| "github.com/mosip/esignet/internal/cache" | ||
| "github.com/mosip/esignet/internal/config" | ||
| "github.com/mosip/esignet/internal/db" | ||
| "github.com/mosip/esignet/internal/handler" | ||
| "github.com/mosip/esignet/internal/server" | ||
| "github.com/mosip/esignet/internal/thunderembed" | ||
| "github.com/mosip/esignet/pkg/logger" | ||
| ) | ||
|
|
||
| func main() { | ||
| os.Exit(run()) | ||
| } | ||
|
|
||
| func run() int { | ||
| // ── 1. Configuration ───────────────────────────────────────────────────── | ||
| cfg, err := config.Load() | ||
| if err != nil { | ||
| // slog default is not yet initialised; fall back to stdlib. | ||
| slog.Error("failed to load config", slog.String("error", err.Error())) | ||
| os.Exit(1) | ||
| return 1 | ||
| } | ||
|
|
||
| // ── 2. Logger ──────────────────────────────────────────────────────────── | ||
|
|
@@ -41,51 +49,80 @@ func main() { | |
| postgres, err := db.NewPostgres(ctx, cfg.Postgres, log) | ||
| if err != nil { | ||
| log.Error("postgres init failed", slog.String("error", err.Error())) | ||
| os.Exit(1) | ||
| return 1 | ||
| } | ||
| defer postgres.Close() | ||
|
|
||
| // ── 5. Redis ───────────────────────────────────────────────────────────── | ||
| redisClient, err := cache.NewRedis(ctx, cfg.Redis, log) | ||
| if err != nil { | ||
| log.Error("redis init failed", slog.String("error", err.Error())) | ||
| os.Exit(1) | ||
| return 1 | ||
| } | ||
| defer func() { | ||
| if err := redisClient.Close(); err != nil { | ||
| log.Warn("redis close error", slog.String("error", err.Error())) | ||
| } | ||
| }() | ||
|
|
||
| pingers := map[string]handler.Pinger{ | ||
| "postgres": postgres, | ||
| "redis": redisClient, | ||
| } | ||
|
|
||
| // ── 6. HTTP Server ─────────────────────────────────────────────────────── | ||
| srv := server.New(cfg.Server, server.Dependencies{ | ||
| DB: postgres, | ||
| Cache: redisClient, | ||
| }, log) | ||
| thunderHome := strings.TrimSpace(cfg.Thunder.Home) | ||
| var ( | ||
| srvStd *server.Server | ||
| srvEmb *thunderembed.Server | ||
| ) | ||
| if thunderHome != "" { | ||
| srvEmb, err = thunderembed.NewServer(cfg, log, pingers) | ||
| if err != nil { | ||
| log.Error("thunder embed init failed", slog.String("error", err.Error())) | ||
| return 1 | ||
| } | ||
| } else { | ||
| srvStd = server.New(cfg.Server, server.Dependencies{ | ||
| DB: postgres, | ||
| Cache: redisClient, | ||
| }, log) | ||
| } | ||
|
|
||
| // Start server in a goroutine so we can listen for shutdown signals below. | ||
| srvErr := make(chan error, 1) | ||
| go func() { | ||
| srvErr <- srv.Start() | ||
| if srvEmb != nil { | ||
| srvErr <- srvEmb.Start() | ||
| return | ||
| } | ||
| srvErr <- srvStd.Start() | ||
| }() | ||
|
|
||
| // ── 7. Block until signal or server error ──────────────────────────────── | ||
| select { | ||
| case err := <-srvErr: | ||
| if err != nil && !errors.Is(err, context.Canceled) { | ||
| log.Error("server exited with error", slog.String("error", err.Error())) | ||
| os.Exit(1) | ||
| return 1 | ||
| } | ||
| case <-ctx.Done(): | ||
| log.Info("shutdown signal received", slog.String("signal", ctx.Err().Error())) | ||
| } | ||
|
|
||
| // ── 8. Graceful shutdown ───────────────────────────────────────────────── | ||
| // Use a fresh background context – the parent ctx is already cancelled. | ||
| if err := srv.Shutdown(context.Background()); err != nil { | ||
| log.Error("graceful shutdown failed", slog.String("error", err.Error())) | ||
| os.Exit(1) | ||
| shutCtx := context.Background() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial | 💤 Low value Document the shutdown context choice. Using Consider adding a comment explaining why a fresh context is used rather than deriving from the signal-cancelled 🤖 Prompt for AI Agents |
||
| if srvEmb != nil { | ||
| if err := srvEmb.Shutdown(shutCtx); err != nil { | ||
| log.Error("graceful shutdown failed", slog.String("error", err.Error())) | ||
| return 1 | ||
| } | ||
| } else { | ||
| if err := srvStd.Shutdown(shutCtx); err != nil { | ||
| log.Error("graceful shutdown failed", slog.String("error", err.Error())) | ||
| return 1 | ||
| } | ||
| } | ||
|
|
||
| log.Info("esignet service stopped cleanly") | ||
| return 0 | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ───────────────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # esignet-service YAML configuration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Copy this file to config.yaml (or any path) and set CONFIG_FILE to point at | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # it. Values here are defaults; any matching environment variable always wins. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Load order (lowest → highest priority): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 1. Struct defaults (hard-coded in the binary) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 2. This YAML file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 3. Environment variables | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Usage: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # CONFIG_FILE=/etc/esignet/config.yaml ./esignet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # CONFIG_FILE=config.yaml make dev | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Tip: commit a config.yaml for local development; never commit secrets. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ───────────────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove or clarify misleading YAML loading documentation. The header comments suggest using This will confuse operators who expect Options to fix:
📝 Option 1: Clarify as reference-only # ─────────────────────────────────────────────────────────────────────────────
# esignet-service YAML configuration
#
-# Copy this file to config.yaml (or any path) and set CONFIG_FILE to point at
-# it. Values here are defaults; any matching environment variable always wins.
+# This file documents the configuration structure and default values for
+# reference. The service reads configuration from ENVIRONMENT VARIABLES only.
#
-# Load order (lowest → highest priority):
-# 1. Struct defaults (hard-coded in the binary)
-# 2. This YAML file
-# 3. Environment variables
+# Use .env.example to see the environment variable names. Each YAML key below
+# corresponds to an environment variable (e.g., server.port → PORT).
#
-# Usage:
-# CONFIG_FILE=/etc/esignet/config.yaml ./esignet
-# CONFIG_FILE=config.yaml make dev
-#
-# Tip: commit a config.yaml for local development; never commit secrets.
+# Tip: use this as a reference when setting environment variables.
# ─────────────────────────────────────────────────────────────────────────────📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── HTTP Server ─────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| server: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| port: 8088 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| read_timeout: 15s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| write_timeout: 15s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| idle_timeout: 60s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shutdown_timeout: 30s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── PostgreSQL ──────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| postgres: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| url: postgres://postgres:postgres@localhost:5432/app?sslmode=disable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max_conns: 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| min_conns: 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max_conn_lifetime: 1h | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| max_conn_idle_time: 30m | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| health_timeout: 5s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── Redis ───────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| redis: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addr: localhost:6379 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| password: "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| db: 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dial_timeout: 5s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| read_timeout: 3s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| write_timeout: 3s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pool_size: 10 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| health_timeout: 5s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ── Logging ─────────────────────────────────────────────────────────────────── | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| log: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # debug | info | warn | error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| level: info | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # json | text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| format: json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Consider defensive initialization ordering.
The
pingersmap is constructed before verifying that dependencies are fully initialized for health checks. If eitherpostgres.Ping()orredisClient.Ping()would fail during health checks due to post-initialization issues, the map still references them.This is acceptable given that initialization errors are already caught at lines 49-66, but consider documenting that
pingersassumes successful initialization.🤖 Prompt for AI Agents