package main import ( "context" "encoding/json" "fmt" "log" "net/http" "os" "runtime/debug" "time" "gitea.neatflow.kr/biosvos/seven-skies/api" "gitea.neatflow.kr/biosvos/seven-skies/internal/app/flow" "gitea.neatflow.kr/biosvos/seven-skies/internal/pkg/broker/nats" "gitea.neatflow.kr/biosvos/seven-skies/internal/pkg/domain" "gitea.neatflow.kr/biosvos/seven-skies/internal/pkg/repository/gorm" "github.com/go-chi/chi/v5" "github.com/joho/godotenv" ) func version() string { info, ok := debug.ReadBuildInfo() if !ok { return "unknown" } return info.Main.Version } type Config struct { NATS_URL string DATABASE_DSN string } func NewConfig() *Config { NATS_URL := os.Getenv("NATS_URL") if NATS_URL == "" { log.Panic("NATS_URL is not set") } DATABASE_DSN := os.Getenv("DATABASE_DSN") if DATABASE_DSN == "" { log.Panic("DATABASE_DSN is not set") } return &Config{ NATS_URL: NATS_URL, DATABASE_DSN: DATABASE_DSN, } } func main() { log.Println("version", version()) err := godotenv.Load() if err == nil { log.Println("env loaded") } config := NewConfig() ctx := context.Background() broker, err := nats.NewBroker(ctx, config.NATS_URL, "SEVEN_SKIES_STREAM", []string{"SEVEN_SKIES_SUBJECT.>"}) if err != nil { log.Panic("error in create broker", err) } defer broker.Close() repo, err := gorm.NewRepository(config.DATABASE_DSN) if err != nil { log.Panic("error in create repository", err) } service := flow.NewFlow(repo) err = broker.Subscribe(ctx, "SEVEN_SKIES_DURABLE", func(topic string, message []byte) error { var event domain.WeatherEvent err := json.Unmarshal(message, &event) if err != nil { log.Println("error in unmarshal", err) return fmt.Errorf("error in unmarshal: %w", err) } err = service.CreateWeather(ctx, &flow.Weather{ Source: string(event.Source), TargetDate: event.TargetDate, ForecastDate: event.ForecastDate, Condition: string(event.Condition), Temperature: float64(event.Temperature.Value), }) if err != nil { return fmt.Errorf("error in create weather: %w", err) } return nil }) if err != nil { log.Panic("error in subscribe", err) } err = serve(service) if err != nil { log.Panic("error in serve", err) } } func serve(service *flow.Flow) error { const timeout = 5 * time.Second server := &http.Server{ //nolint:exhaustruct ReadHeaderTimeout: timeout, Handler: api.HandlerFromMux(api.NewStrictHandler(NewHandler(service), nil), chi.NewRouter()), Addr: "0.0.0.0:8080", } err := server.ListenAndServe() if err != nil { return fmt.Errorf("error in listen and serve: %w", err) } return nil }