選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

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