Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

140 righe
3.9 KiB

  1. package controller
  2. import (
  3. "context"
  4. "encoding/json"
  5. "log/slog"
  6. "net/http"
  7. "github.com/AFASystems/presence/internal/pkg/api/response"
  8. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  9. "github.com/AFASystems/presence/internal/pkg/model"
  10. "github.com/AFASystems/presence/internal/pkg/validation"
  11. "github.com/gorilla/mux"
  12. "github.com/segmentio/kafka-go"
  13. "gorm.io/gorm"
  14. )
  15. func SendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate, context context.Context) error {
  16. valueStr, err := json.Marshal(&value)
  17. if err != nil {
  18. slog.Error("error encoding", "error", err)
  19. return err
  20. }
  21. msg := kafka.Message{
  22. Value: valueStr,
  23. }
  24. if err := kafkaclient.Write(context, writer, msg); err != nil {
  25. slog.Error("error sending kafka message", "error", err)
  26. return err
  27. }
  28. return nil
  29. }
  30. func TrackerAdd(db *gorm.DB, writer *kafka.Writer, context context.Context) http.HandlerFunc {
  31. return func(w http.ResponseWriter, r *http.Request) {
  32. var tracker model.Tracker
  33. if err := json.NewDecoder(r.Body).Decode(&tracker); err != nil {
  34. response.BadRequest(w, "invalid request body")
  35. return
  36. }
  37. if err := validation.Struct(&tracker); err != nil {
  38. response.BadRequest(w, err.Error())
  39. return
  40. }
  41. if err := db.WithContext(context).Create(&tracker).Error; err != nil {
  42. response.InternalError(w, "failed to create tracker", err)
  43. return
  44. }
  45. apiUpdate := model.ApiUpdate{
  46. Method: "POST",
  47. ID: tracker.ID,
  48. MAC: tracker.MAC,
  49. }
  50. if err := SendKafkaMessage(writer, &apiUpdate, context); err != nil {
  51. slog.Error("error sending Kafka POST message", "err", err)
  52. response.InternalError(w, "failed to publish tracker update", err)
  53. return
  54. }
  55. response.JSON(w, http.StatusCreated, map[string]string{"status": "created"})
  56. }
  57. }
  58. func TrackerList(db *gorm.DB, context context.Context) http.HandlerFunc {
  59. return func(w http.ResponseWriter, r *http.Request) {
  60. var list []model.Tracker
  61. if err := db.WithContext(context).Find(&list).Error; err != nil {
  62. response.InternalError(w, "failed to list trackers", err)
  63. return
  64. }
  65. response.JSON(w, http.StatusOK, list)
  66. }
  67. }
  68. func TrackerUpdate(db *gorm.DB, context context.Context) http.HandlerFunc {
  69. return func(w http.ResponseWriter, r *http.Request) {
  70. var tracker model.Tracker
  71. if err := json.NewDecoder(r.Body).Decode(&tracker); err != nil {
  72. response.BadRequest(w, "invalid request body")
  73. return
  74. }
  75. if err := validation.Struct(&tracker); err != nil {
  76. response.BadRequest(w, err.Error())
  77. return
  78. }
  79. id := tracker.ID
  80. if err := db.WithContext(context).First(&model.Tracker{}, "id = ?", id).Error; err != nil {
  81. response.NotFound(w, "tracker not found")
  82. return
  83. }
  84. if err := db.WithContext(context).Save(&tracker).Error; err != nil {
  85. response.InternalError(w, "failed to update tracker", err)
  86. return
  87. }
  88. response.JSON(w, http.StatusOK, map[string]string{"status": "updated"})
  89. }
  90. }
  91. func TrackerDelete(db *gorm.DB, writer *kafka.Writer, context context.Context) http.HandlerFunc {
  92. return func(w http.ResponseWriter, r *http.Request) {
  93. id := mux.Vars(r)["id"]
  94. var tracker model.Tracker
  95. if err := db.WithContext(context).First(&tracker, "id = ?", id).Error; err != nil {
  96. response.NotFound(w, "tracker not found")
  97. return
  98. }
  99. res := db.WithContext(context).Delete(&model.Tracker{}, "id = ?", id)
  100. if res.RowsAffected == 0 {
  101. response.NotFound(w, "tracker not found")
  102. return
  103. }
  104. if res.Error != nil {
  105. response.InternalError(w, "failed to delete tracker", res.Error)
  106. return
  107. }
  108. apiUpdate := model.ApiUpdate{
  109. Method: "DELETE",
  110. MAC: tracker.MAC,
  111. }
  112. slog.Info("sending DELETE tracker message", "id", id)
  113. if err := SendKafkaMessage(writer, &apiUpdate, context); err != nil {
  114. slog.Error("error sending Kafka DELETE message", "err", err)
  115. response.InternalError(w, "failed to publish tracker deletion", err)
  116. return
  117. }
  118. response.JSON(w, http.StatusOK, map[string]string{"status": "deleted"})
  119. }
  120. }