您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

131 行
3.2 KiB

  1. package main
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/hex"
  6. "fmt"
  7. "log/slog"
  8. "os/signal"
  9. "strings"
  10. "sync"
  11. "syscall"
  12. "github.com/AFASystems/presence/internal/pkg/common/appcontext"
  13. "github.com/AFASystems/presence/internal/pkg/common/utils"
  14. "github.com/AFASystems/presence/internal/pkg/config"
  15. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  16. "github.com/AFASystems/presence/internal/pkg/logger"
  17. "github.com/AFASystems/presence/internal/pkg/model"
  18. "github.com/segmentio/kafka-go"
  19. )
  20. var wg sync.WaitGroup
  21. func main() {
  22. // Load global context to init beacons and latest list
  23. appState := appcontext.NewAppState()
  24. cfg := config.Load()
  25. parserRegistry := model.ParserRegistry{
  26. ParserList: make(map[string]model.BeaconParser),
  27. }
  28. // Set logger -> terminal and log file
  29. slog.SetDefault(logger.CreateLogger("decoder.log"))
  30. // define context
  31. ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
  32. defer stop()
  33. rawReader := appState.AddKafkaReader(cfg.KafkaURL, "rawbeacons", "gid-raw")
  34. parserReader := appState.AddKafkaReader(cfg.KafkaURL, "parser", "gid-parser")
  35. alertWriter := appState.AddKafkaWriter(cfg.KafkaURL, "alertbeacons")
  36. slog.Info("Decoder initialized, subscribed to Kafka topics")
  37. chRaw := make(chan model.BeaconAdvertisement, 2000)
  38. chParser := make(chan model.KafkaParser, 200)
  39. wg.Add(3)
  40. go kafkaclient.Consume(rawReader, chRaw, ctx, &wg)
  41. go kafkaclient.Consume(parserReader, chParser, ctx, &wg)
  42. eventloop:
  43. for {
  44. select {
  45. case <-ctx.Done():
  46. break eventloop
  47. case msg := <-chRaw:
  48. processIncoming(msg, appState, alertWriter, &parserRegistry)
  49. case msg := <-chParser:
  50. switch msg.ID {
  51. case "add":
  52. config := msg.Config
  53. parserRegistry.Register(config.Name, config)
  54. case "delete":
  55. parserRegistry.Unregister(msg.Name)
  56. case "update":
  57. config := msg.Config
  58. parserRegistry.Register(config.Name, config)
  59. }
  60. }
  61. }
  62. slog.Info("broken out of the main event loop")
  63. wg.Wait()
  64. slog.Info("All go routines have stopped, Beggining to close Kafka connections")
  65. appState.CleanKafkaReaders()
  66. appState.CleanKafkaWriters()
  67. }
  68. func processIncoming(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, parserRegistry *model.ParserRegistry) {
  69. err := decodeBeacon(adv, appState, writer, parserRegistry)
  70. if err != nil {
  71. eMsg := fmt.Sprintf("Error in decoding: %v", err)
  72. fmt.Println(eMsg)
  73. return
  74. }
  75. }
  76. func decodeBeacon(adv model.BeaconAdvertisement, appState *appcontext.AppState, writer *kafka.Writer, parserRegistry *model.ParserRegistry) error {
  77. beacon := strings.TrimSpace(adv.Data)
  78. id := adv.ID
  79. if beacon == "" {
  80. return nil
  81. }
  82. b, err := hex.DecodeString(beacon)
  83. if err != nil {
  84. return err
  85. }
  86. b = utils.RemoveFlagBytes(b)
  87. indeces := utils.ParseADFast(b)
  88. event := utils.LoopADStructures(b, indeces, id, parserRegistry)
  89. if event.ID == "" {
  90. return nil
  91. }
  92. prevEvent, ok := appState.GetBeaconEvent(id)
  93. appState.UpdateBeaconEvent(id, event)
  94. if ok && bytes.Equal(prevEvent.Hash(), event.Hash()) {
  95. return nil
  96. }
  97. eMsg, err := event.ToJSON()
  98. if err != nil {
  99. return err
  100. }
  101. if err := writer.WriteMessages(context.Background(), kafka.Message{Value: eMsg}); err != nil {
  102. return err
  103. }
  104. return nil
  105. }