mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-11-01 01:22:15 +00:00
* refactor: Rename handler package to handlers in carrier-connector - Rename internal/handler directory to internal/handlers - Update handler import path in main.go and routes.go * feat: Add SM-DP+ handler with multi-carrier management and profile operations - Add SMDPHandler struct with manager field and NewSMDPHandler constructor - Add AddCarrier endpoint with JSON binding and carrier configuration support - Add RemoveCarrier endpoint with carrier ID parameter validation - Add DownloadProfile endpoint with 30-second timeout and context cancellation - Add GetCarrierStatus endpoint returning all carriers with timestamp - Add GetProfileStatus endpoint with EID/ICCID validation * feat: Add SM-DP+ integration layer with multi-carrier system initialization and route registration - Add SMDPIntegration struct with service, handler, repository, and logger fields - Add NewSMDPIntegration constructor with default carrier initialization - Add InitializeSystem method with carrier health logging and status tracking - Add RegisterRoutes method with profile, carrier, health, and metrics endpoints - Add healthHandler with carrier health status aggregation and degraded state detection - Add metricsHandler * feat: Add SM-DP+ service layer with multi-carrier management and profile download operations - Add SMDPService struct with manager, repository, and logger fields - Add NewSMDPService constructor with default config and background health checking - Add InitializeDefaultCarriers with AT&T, Verizon, and T-Mobile DE configurations - Add DownloadProfile method with context support and request logging - Add GetOptimalCarrier wrapping SelectCarrier for best carrier selection - Add GetCarrierHealth returning * feat: Add SM-DP+ manager with multi-carrier load balancing, health checking, and profile operations - Add DefaultManagerConfig with 30s health checks, 3 retries, and circuit breaker configuration - Add CarrierConfig struct with ES2 settings, MCC/MNC, priority, and feature support - Add ToCarrier method converting CarrierConfig to Carrier with metrics and capabilities - Add HealthChecker with periodic carrier health monitoring and status evaluation - Add LoadBalancer with weighted round-robin, least
105 lines
3.6 KiB
Go
105 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/joho/godotenv"
|
|
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/config"
|
|
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/es2"
|
|
handler "github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/handlers"
|
|
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/mq"
|
|
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/repository"
|
|
"github.com/nutcas3/telecom-platform/apps/carrier-connector/internal/webhook"
|
|
"github.com/rs/zerolog"
|
|
csrf "github.com/utrack/gin-csrf"
|
|
)
|
|
|
|
func main() {
|
|
handler.Logger = zerolog.New(os.Stdout).With().
|
|
Timestamp().
|
|
Str("service", "carrier-connector").
|
|
Logger()
|
|
|
|
if err := godotenv.Load(); err != nil {
|
|
handler.Logger.Info().Msg("No .env file found, using system environment")
|
|
}
|
|
|
|
client := es2.NewES2Client(&config.ES2Config{
|
|
BaseURL: handler.GetEnv("SMDP_URL", "https://smdp.example.com"),
|
|
APIKey: handler.GetEnv("SMDP_API_KEY", "test-api-key"),
|
|
FunctionalityRequesterID: handler.GetEnv("FUNCTIONALITY_REQUESTER_ID", "carrier-connector"),
|
|
InsecureSkipVerify: handler.GetEnv("INSECURE_SKIP_VERIFY", "true") == "true",
|
|
})
|
|
port := handler.GetEnv("PORT", "8080")
|
|
|
|
router := gin.Default()
|
|
|
|
// Add CSRF protection middleware
|
|
csrfSecret := os.Getenv("CSRF_SECRET")
|
|
if csrfSecret == "" {
|
|
csrfSecret = "change-me-in-production-csrf-secret-32-chars-min"
|
|
handler.Logger.Warn().Msg("Using default CSRF secret, set CSRF_SECRET environment variable")
|
|
}
|
|
router.Use(csrf.Middleware(csrf.Options{
|
|
Secret: csrfSecret,
|
|
}))
|
|
|
|
router.Use(gin.LoggerWithFormatter(func(p gin.LogFormatterParams) string {
|
|
return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
|
|
p.ClientIP, p.TimeStamp.Format(time.RFC1123),
|
|
p.Method, p.Path, p.Request.Proto,
|
|
p.StatusCode, p.Latency, p.Request.UserAgent(), p.ErrorMessage,
|
|
)
|
|
}))
|
|
router.Use(gin.Recovery())
|
|
|
|
dsn := handler.GetEnv("DATABASE_DSN", "")
|
|
if dsn == "" {
|
|
handler.Logger.Fatal().Msg("DATABASE_DSN is required (no in-memory fallback)")
|
|
}
|
|
postgresRepo, err := repository.NewPostgresProfileStore(dsn)
|
|
if err != nil {
|
|
handler.Logger.Fatal().Err(err).Msg("Failed to connect to Postgres")
|
|
}
|
|
defer postgresRepo.Close()
|
|
|
|
// Wrap with cache (5 minute TTL)
|
|
profileRepo := repository.NewCachedProfileStore(postgresRepo, 5*time.Minute)
|
|
defer profileRepo.Close()
|
|
|
|
// Initialize webhook client for api-server notifications
|
|
webhookURL := handler.GetEnv("API_SERVER_WEBHOOK_URL", "")
|
|
webhookAPIKey := handler.GetEnv("API_SERVER_WEBHOOK_API_KEY", "")
|
|
webhookClient := webhook.NewWebhookClient(webhookURL, webhookAPIKey)
|
|
|
|
// Initialize message queue for async events (optional)
|
|
var messageQueue *mq.MessageQueue
|
|
rabbitmqURL := handler.GetEnv("RABBITMQ_URL", "")
|
|
if rabbitmqURL != "" {
|
|
mq, err := mq.NewMessageQueue(rabbitmqURL)
|
|
if err != nil {
|
|
handler.Logger.Warn().Err(err).Msg("Failed to connect to RabbitMQ, continuing without message queue")
|
|
} else {
|
|
// Declare profile events queue
|
|
if err := mq.DeclareQueue("profile-events"); err != nil {
|
|
handler.Logger.Warn().Err(err).Msg("Failed to declare profile-events queue")
|
|
mq.Close()
|
|
} else {
|
|
messageQueue = mq
|
|
handler.Logger.Info().Msg("Message queue initialized")
|
|
defer messageQueue.Close()
|
|
}
|
|
}
|
|
}
|
|
|
|
setupRoutes(router, client, profileRepo, webhookClient, messageQueue)
|
|
|
|
handler.Logger.Info().Str("port", port).Msg("Carrier Connector API server starting")
|
|
if err := router.Run(":" + port); err != nil {
|
|
handler.Logger.Fatal().Err(err).Msg("Failed to start server")
|
|
}
|
|
}
|