2022-08-13 23:33:50 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"basic-sensor-receiver/app"
|
2022-08-21 20:51:14 +02:00
|
|
|
"basic-sensor-receiver/middleware"
|
2022-08-13 23:39:18 +02:00
|
|
|
"basic-sensor-receiver/routes"
|
2024-04-01 08:37:57 +02:00
|
|
|
"context"
|
2022-08-13 23:33:50 +02:00
|
|
|
"fmt"
|
2022-08-14 23:51:32 +02:00
|
|
|
"log"
|
2024-04-01 08:37:57 +02:00
|
|
|
"net/http"
|
|
|
|
|
"os/signal"
|
|
|
|
|
"syscall"
|
2022-08-13 23:33:50 +02:00
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2022-08-14 23:51:32 +02:00
|
|
|
"github.com/joho/godotenv"
|
2022-08-13 23:33:50 +02:00
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
2022-08-14 23:51:32 +02:00
|
|
|
err := godotenv.Load()
|
|
|
|
|
if err != nil {
|
2024-03-31 18:33:56 +02:00
|
|
|
log.Println("Error loading .env file: ", err)
|
2022-08-14 23:51:32 +02:00
|
|
|
}
|
|
|
|
|
|
2022-08-13 23:33:50 +02:00
|
|
|
server := app.InitializeServer()
|
|
|
|
|
|
|
|
|
|
gin.SetMode(server.Config.Mode)
|
|
|
|
|
|
|
|
|
|
router := gin.Default()
|
|
|
|
|
|
2022-08-21 22:27:21 +02:00
|
|
|
// Front-end resources
|
2022-08-21 20:51:14 +02:00
|
|
|
router.StaticFile("/", "client/index.html")
|
2022-08-21 23:28:29 +02:00
|
|
|
router.Static("/assets", "client/assets")
|
2022-08-13 23:33:50 +02:00
|
|
|
|
2022-08-21 22:27:21 +02:00
|
|
|
// Only allow CORS in development mode
|
2024-03-29 21:05:21 +01:00
|
|
|
if server.Config.Mode == "debug" {
|
2022-08-21 22:27:21 +02:00
|
|
|
router.Use(middleware.CorsMiddleware())
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-31 18:33:56 +02:00
|
|
|
if server.Config.AuthEnabled {
|
|
|
|
|
// User login route
|
|
|
|
|
router.POST("/api/login", routes.Login(server))
|
|
|
|
|
}
|
2022-08-13 23:33:50 +02:00
|
|
|
|
2022-08-21 22:27:21 +02:00
|
|
|
// Routes that are only accessible after logging in
|
2022-08-21 20:51:14 +02:00
|
|
|
loginProtected := router.Group("/", middleware.LoginAuthMiddleware(server))
|
|
|
|
|
loginProtected.GET("/api/sensors", routes.GetSensors(server))
|
2022-08-28 11:56:03 +02:00
|
|
|
loginProtected.POST("/api/sensors", routes.PostSensors(server))
|
2022-08-28 12:30:37 +02:00
|
|
|
loginProtected.GET("/api/sensors/:sensor", routes.GetSensor(server))
|
2022-08-28 21:47:36 +02:00
|
|
|
loginProtected.PUT("/api/sensors/:sensor", routes.PutSensor(server))
|
|
|
|
|
loginProtected.DELETE("/api/sensors/:sensor", routes.DeleteSensor(server))
|
2022-08-24 09:46:14 +02:00
|
|
|
loginProtected.GET("/api/sensors/:sensor/values/latest", routes.GetSensorLatestValue(server))
|
2022-08-23 23:35:36 +02:00
|
|
|
loginProtected.GET("/api/sensors/:sensor/values", routes.GetSensorValues(server))
|
2022-08-28 11:56:03 +02:00
|
|
|
//loginProtected.GET("/api/sensors/:sensor/config", routes.GetSensorConfig(server))
|
|
|
|
|
//loginProtected.PUT("/api/sensors/:sensor/config/:key", routes.PutSensorConfig(server))
|
2022-08-23 23:35:36 +02:00
|
|
|
loginProtected.GET("/api/dashboards", routes.GetDashboards(server))
|
|
|
|
|
loginProtected.POST("/api/dashboards", routes.PostDashboard(server))
|
|
|
|
|
loginProtected.GET("/api/dashboards/:id", routes.GetDashboardById(server))
|
|
|
|
|
loginProtected.PUT("/api/dashboards/:id", routes.PutDashboard(server))
|
2022-09-03 21:59:37 +02:00
|
|
|
loginProtected.DELETE("/api/dashboards/:id", routes.DeleteDashboard(server))
|
2024-03-29 09:55:51 +01:00
|
|
|
loginProtected.GET("/api/alerts", routes.GetAlerts(server))
|
|
|
|
|
loginProtected.POST("/api/alerts", routes.PostAlerts(server))
|
|
|
|
|
loginProtected.GET("/api/alerts/:alertId", routes.GetAlert(server))
|
|
|
|
|
loginProtected.PUT("/api/alerts/:alertId", routes.PutAlert(server))
|
|
|
|
|
loginProtected.DELETE("/api/alerts/:alertId", routes.DeleteAlert(server))
|
2024-03-29 21:05:21 +01:00
|
|
|
loginProtected.GET("/api/contact-points", routes.GetContactPoints(server))
|
|
|
|
|
loginProtected.POST("/api/contact-points", routes.PostContactPoints(server))
|
|
|
|
|
loginProtected.GET("/api/contact-points/:contactPointId", routes.GetContactPoint(server))
|
|
|
|
|
loginProtected.PUT("/api/contact-points/:contactPointId", routes.PutContactPoint(server))
|
|
|
|
|
loginProtected.DELETE("/api/contact-points/:contactPointId", routes.DeleteContactPoint(server))
|
2024-03-31 09:50:09 +02:00
|
|
|
loginProtected.POST("/api/contact-points/test", routes.TestContactPoint(server))
|
2024-04-01 19:42:20 +02:00
|
|
|
loginProtected.GET("/api/mqtt/brokers", routes.GetMQTTBrokers(server))
|
|
|
|
|
loginProtected.POST("/api/mqtt/brokers", routes.PostMQTTBroker(server))
|
|
|
|
|
loginProtected.GET("/api/mqtt/brokers/:brokerId", routes.GetMQTTBroker(server))
|
|
|
|
|
loginProtected.PUT("/api/mqtt/brokers/:brokerId", routes.PutMQTTBroker(server))
|
|
|
|
|
loginProtected.DELETE("/api/mqtt/brokers/:brokerId", routes.DeleteMQTTBroker(server))
|
|
|
|
|
loginProtected.POST("/api/mqtt/brokers/:brokerId/publish", routes.PostMQTTBrokerPublish(server))
|
2024-03-31 18:33:56 +02:00
|
|
|
|
|
|
|
|
if server.Config.AuthEnabled {
|
|
|
|
|
loginProtected.POST("/api/logout", routes.Logout(server))
|
|
|
|
|
}
|
2022-08-21 20:51:14 +02:00
|
|
|
|
2022-08-21 22:27:21 +02:00
|
|
|
// Routes accessible using auth key
|
2022-08-21 20:51:14 +02:00
|
|
|
keyProtected := router.Group("/", middleware.KeyAuthMiddleware(server))
|
2022-08-23 23:35:36 +02:00
|
|
|
keyProtected.POST("/api/sensors/:sensor/values", routes.PostSensorValues(server))
|
2022-08-13 23:33:50 +02:00
|
|
|
|
2022-08-21 22:48:00 +02:00
|
|
|
// Starts session cleanup goroutine
|
|
|
|
|
server.StartCleaner()
|
|
|
|
|
|
2024-03-29 09:55:51 +01:00
|
|
|
// Starts alerts handling goroutine
|
|
|
|
|
server.StartAlerts()
|
|
|
|
|
|
2025-03-04 12:09:15 +01:00
|
|
|
// MQTT listeners
|
|
|
|
|
server.EnsureMqttListeners()
|
|
|
|
|
|
2024-04-01 08:37:57 +02:00
|
|
|
// Graceful shutdown using SIGTERM or SIGINT
|
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
|
defer stop()
|
|
|
|
|
|
|
|
|
|
// Prepare http server
|
2024-03-31 18:33:56 +02:00
|
|
|
address := fmt.Sprintf("%s:%d", server.Config.Ip, server.Config.Port)
|
2024-04-01 08:37:57 +02:00
|
|
|
srv := &http.Server{
|
|
|
|
|
Addr: address,
|
|
|
|
|
Handler: router,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Run the server in a goroutine so that it doesn't block and we can stop it later
|
|
|
|
|
go func() {
|
|
|
|
|
log.Println("Running server on", address)
|
|
|
|
|
|
|
|
|
|
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
|
|
|
log.Fatalf("Listen: %s\n", err)
|
|
|
|
|
}
|
|
|
|
|
}()
|
2024-03-31 18:33:56 +02:00
|
|
|
|
2024-04-01 08:37:57 +02:00
|
|
|
// Wait for shutdown signal
|
|
|
|
|
<-ctx.Done()
|
|
|
|
|
|
|
|
|
|
// Shutdown the server
|
|
|
|
|
log.Println("Shutting down server...")
|
|
|
|
|
|
|
|
|
|
if err := srv.Shutdown(context.TODO()); err != nil {
|
|
|
|
|
log.Fatalf("Server shutdown failed: %v", err)
|
|
|
|
|
}
|
2024-03-31 18:33:56 +02:00
|
|
|
|
2024-04-01 08:38:33 +02:00
|
|
|
if err := server.DB.Close(); err != nil {
|
|
|
|
|
log.Fatalf("Database close failed: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-01 08:37:57 +02:00
|
|
|
log.Println("Server stopped")
|
2022-08-13 23:33:50 +02:00
|
|
|
}
|