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.
 
 
 
 

198 righe
5.1 KiB

  1. package main
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "strings"
  8. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  9. "github.com/AFASystems/presence/internal/pkg/model"
  10. "github.com/gorilla/handlers"
  11. "github.com/gorilla/mux"
  12. "github.com/redis/go-redis/v9"
  13. "github.com/segmentio/kafka-go"
  14. )
  15. func main() {
  16. HttpServer("0.0.0.0:1902")
  17. }
  18. func HttpServer(addr string) {
  19. headersOk := handlers.AllowedHeaders([]string{"X-Requested-With"})
  20. originsOk := handlers.AllowedOrigins([]string{"*"})
  21. methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"})
  22. // Kafka writer that relays messages
  23. writer := kafkaclient.KafkaWriter("kafka:9092", "apibeacons")
  24. defer writer.Close()
  25. settingsWriter := kafkaclient.KafkaWriter("kafka:9092", "settings")
  26. defer settingsWriter.Close()
  27. r := mux.NewRouter()
  28. client := redis.NewClient(&redis.Options{
  29. Addr: "valkey:6379",
  30. Password: "",
  31. })
  32. // For now just add beacon DELETE / GET / POST / PUT methods
  33. r.HandleFunc("/api/beacons/{beacon_id}", beaconsDeleteHandler(writer)).Methods("DELETE")
  34. r.HandleFunc("/api/beacons", beaconsListHandler(client)).Methods("GET")
  35. r.HandleFunc("/api/beacons", beaconsAddHandler(writer)).Methods("POST")
  36. r.HandleFunc("/api/beacons", beaconsAddHandler(writer)).Methods("PUT")
  37. r.HandleFunc("/api/settings", settingsListHandler(client)).Methods("GET")
  38. r.HandleFunc("/api/settings", settingsEditHandler(settingsWriter)).Methods("POST")
  39. http.ListenAndServe(addr, handlers.CORS(originsOk, headersOk, methodsOk)(r))
  40. }
  41. func sendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate) bool {
  42. valueStr, err := json.Marshal(&value)
  43. if err != nil {
  44. fmt.Println("error in encoding: ", err)
  45. return false
  46. }
  47. msg := kafka.Message{
  48. Value: valueStr,
  49. }
  50. err = writer.WriteMessages(context.Background(), msg)
  51. if err != nil {
  52. fmt.Println("Error in sending kafka message: ")
  53. return false
  54. }
  55. return true
  56. }
  57. func beaconsDeleteHandler(writer *kafka.Writer) http.HandlerFunc {
  58. return func(w http.ResponseWriter, r *http.Request) {
  59. vars := mux.Vars(r)
  60. beaconId := vars["beacon_id"]
  61. apiUpdate := model.ApiUpdate{
  62. Method: "DELETE",
  63. ID: beaconId,
  64. }
  65. flag := sendKafkaMessage(writer, &apiUpdate)
  66. if !flag {
  67. fmt.Println("error in sending Kafka message")
  68. http.Error(w, "Error in sending kafka message", 500)
  69. return
  70. }
  71. w.Write([]byte("ok"))
  72. }
  73. }
  74. func beaconsAddHandler(writer *kafka.Writer) http.HandlerFunc {
  75. return func(w http.ResponseWriter, r *http.Request) {
  76. decoder := json.NewDecoder(r.Body)
  77. var inBeacon model.Beacon
  78. err := decoder.Decode(&inBeacon)
  79. if err != nil {
  80. http.Error(w, err.Error(), 400)
  81. return
  82. }
  83. if (len(strings.TrimSpace(inBeacon.Name)) == 0) || (len(strings.TrimSpace(inBeacon.Beacon_id)) == 0) {
  84. http.Error(w, "name and beacon_id cannot be blank", 400)
  85. return
  86. }
  87. apiUpdate := model.ApiUpdate{
  88. Method: "POST",
  89. Beacon: inBeacon,
  90. }
  91. flag := sendKafkaMessage(writer, &apiUpdate)
  92. if !flag {
  93. fmt.Println("error in sending Kafka message")
  94. http.Error(w, "Error in sending kafka message", 500)
  95. return
  96. }
  97. w.Write([]byte("ok"))
  98. }
  99. }
  100. func beaconsListHandler(client *redis.Client) http.HandlerFunc {
  101. return func(w http.ResponseWriter, r *http.Request) {
  102. beaconsList, err := client.Get(context.Background(), "beaconsList").Result()
  103. if err == redis.Nil {
  104. fmt.Println("no beacons list, starting empty")
  105. http.Error(w, "list is empty", 500)
  106. } else if err != nil {
  107. http.Error(w, "Internal server error", 500)
  108. panic(err)
  109. } else {
  110. w.Write([]byte(beaconsList))
  111. }
  112. }
  113. }
  114. func settingsListHandler(client *redis.Client) http.HandlerFunc {
  115. return func(w http.ResponseWriter, r *http.Request) {
  116. settings, err := client.Get(context.Background(), "settings").Result()
  117. if err == redis.Nil {
  118. fmt.Println("no settings persisted, starting empty")
  119. http.Error(w, "list is empty", 500)
  120. } else if err != nil {
  121. http.Error(w, "Internal server error", 500)
  122. panic(err)
  123. } else {
  124. w.Write([]byte(settings))
  125. }
  126. }
  127. }
  128. func settingsEditHandler(writer *kafka.Writer) http.HandlerFunc {
  129. return func(w http.ResponseWriter, r *http.Request) {
  130. decoder := json.NewDecoder(r.Body)
  131. var inSettings model.SettingsVal
  132. if err := decoder.Decode(&inSettings); err != nil {
  133. http.Error(w, err.Error(), 400)
  134. fmt.Println("Error in decoding Settings body: ", err)
  135. return
  136. }
  137. if !settingsCheck(inSettings) {
  138. http.Error(w, "values must be greater than 0", 400)
  139. fmt.Println("settings values must be greater than 0")
  140. return
  141. }
  142. valueStr, err := json.Marshal(&inSettings)
  143. if err != nil {
  144. http.Error(w, "Error in encoding settings", 500)
  145. fmt.Println("Error in encoding settings: ", err)
  146. return
  147. }
  148. msg := kafka.Message{
  149. Value: valueStr,
  150. }
  151. if err := writer.WriteMessages(context.Background(), msg); err != nil {
  152. fmt.Println("error in sending Kafka message")
  153. http.Error(w, "Error in sending kafka message", 500)
  154. return
  155. }
  156. w.Write([]byte("ok"))
  157. }
  158. }
  159. func settingsCheck(settings model.SettingsVal) bool {
  160. if settings.Location_confidence <= 0 || settings.Last_seen_threshold <= 0 || settings.HA_send_interval <= 0 {
  161. return false
  162. }
  163. return true
  164. }