183 lines
4.0 KiB
Go
183 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
|
|
"context"
|
|
"jokes-bapak2-api/core/joke"
|
|
"jokes-bapak2-api/routes"
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
|
|
"time"
|
|
|
|
"github.com/allegro/bigcache/v3"
|
|
"github.com/getsentry/sentry-go"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/rs/cors"
|
|
)
|
|
|
|
func main() {
|
|
redisURL, ok := os.LookupEnv("REDIS_URL")
|
|
if !ok {
|
|
redisURL = "redis://@localhost:6379"
|
|
}
|
|
|
|
minioHost, ok := os.LookupEnv("MINIO_HOST")
|
|
if !ok {
|
|
minioHost = "localhost:9000"
|
|
}
|
|
|
|
minioRegion, ok := os.LookupEnv("MINIO_REGION")
|
|
if !ok {
|
|
minioRegion = ""
|
|
}
|
|
|
|
minioSecure, ok := os.LookupEnv("MINIO_SECURE")
|
|
if !ok {
|
|
minioSecure = "false"
|
|
}
|
|
|
|
minioID, ok := os.LookupEnv("MINIO_ACCESS_ID")
|
|
if !ok {
|
|
minioID = "minio"
|
|
}
|
|
|
|
minioSecret, ok := os.LookupEnv("MINIO_SECRET_KEY")
|
|
if !ok {
|
|
minioSecret = "password"
|
|
}
|
|
|
|
minioToken, ok := os.LookupEnv("MINIO_TOKEN")
|
|
if !ok {
|
|
minioToken = ""
|
|
}
|
|
|
|
sentryDsn, ok := os.LookupEnv("SENTRY_DSN")
|
|
if !ok {
|
|
sentryDsn = ""
|
|
}
|
|
|
|
port, ok := os.LookupEnv("PORT")
|
|
if !ok {
|
|
port = "5000"
|
|
}
|
|
|
|
hostname, ok := os.LookupEnv("HOSTNAME")
|
|
if !ok {
|
|
hostname = "127.0.0.1"
|
|
}
|
|
|
|
environment, ok := os.LookupEnv("ENVIRONMENT")
|
|
if !ok {
|
|
environment = "development"
|
|
}
|
|
|
|
// Setup In Memory
|
|
memory, err := bigcache.NewBigCache(bigcache.DefaultConfig(10 * time.Minute))
|
|
if err != nil {
|
|
log.Panicln(err)
|
|
}
|
|
defer memory.Close()
|
|
|
|
// Setup MinIO
|
|
minioClient, err := minio.New(minioHost, &minio.Options{
|
|
Creds: credentials.NewStaticV4(minioID, minioSecret, minioToken),
|
|
Region: minioRegion,
|
|
Secure: minioSecure == "true",
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("setting up minio client: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
parsedRedisURL, err := redis.ParseURL(redisURL)
|
|
if err != nil {
|
|
log.Fatalf("parsing redis url: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
redisClient := redis.NewClient(parsedRedisURL)
|
|
defer func() {
|
|
err := redisClient.Close()
|
|
if err != nil {
|
|
log.Printf("closing redis client: %s", err.Error())
|
|
}
|
|
}()
|
|
|
|
// Setup Sentry
|
|
err = sentry.Init(sentry.ClientOptions{
|
|
Dsn: sentryDsn,
|
|
Environment: environment,
|
|
AttachStacktrace: true,
|
|
// Enable printing of SDK debug messages.
|
|
// Useful when getting started or trying to figure something out.
|
|
Debug: environment != "production",
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("setting up sentry: %s", err.Error())
|
|
return
|
|
}
|
|
defer sentry.Flush(2 * time.Second)
|
|
|
|
setupCtx, setupCancel := context.WithDeadline(context.Background(), time.Now().Add(time.Minute*4))
|
|
defer setupCancel()
|
|
|
|
_, _, err = joke.GetTodaysJoke(setupCtx, minioClient, redisClient, memory)
|
|
if err != nil {
|
|
log.Fatalf("getting initial joke data: %s", err.Error())
|
|
return
|
|
}
|
|
|
|
healthRouter := routes.Health(minioClient, redisClient)
|
|
jokeRouter := routes.Joke(minioClient, redisClient, memory)
|
|
|
|
router := chi.NewRouter()
|
|
|
|
router.Use(cors.New(cors.Options{
|
|
AllowedMethods: []string{http.MethodGet},
|
|
AllowCredentials: false,
|
|
MaxAge: int(60 * 60 * 24 * 365),
|
|
Debug: false,
|
|
}).Handler)
|
|
|
|
router.Mount("/health", healthRouter)
|
|
router.Mount("/", jokeRouter)
|
|
|
|
server := &http.Server{
|
|
Handler: router,
|
|
Addr: net.JoinHostPort(hostname, port),
|
|
ReadTimeout: time.Minute,
|
|
WriteTimeout: time.Minute,
|
|
IdleTimeout: time.Second * 30,
|
|
ReadHeaderTimeout: time.Minute,
|
|
}
|
|
|
|
exitSignal := make(chan os.Signal, 1)
|
|
signal.Notify(exitSignal, os.Interrupt)
|
|
|
|
go func() {
|
|
err := server.ListenAndServe()
|
|
if err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
log.Fatalf("listening http server: %v", err)
|
|
}
|
|
}()
|
|
|
|
<-exitSignal
|
|
|
|
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), time.Second*30)
|
|
defer shutdownCancel()
|
|
|
|
err = server.Shutdown(shutdownCtx)
|
|
if err != nil {
|
|
log.Printf("shutting down http server: %v", err)
|
|
}
|
|
}
|