| @@ -2,7 +2,6 @@ package decoder | |||||
| import ( | import ( | ||||
| "context" | "context" | ||||
| "fmt" | |||||
| "log/slog" | "log/slog" | ||||
| "sync" | "sync" | ||||
| "time" | "time" | ||||
| @@ -84,7 +83,6 @@ func (a *DecoderApp) Run(ctx context.Context) { | |||||
| continue | continue | ||||
| } | } | ||||
| case msg := <-a.ChRaw: | case msg := <-a.ChRaw: | ||||
| fmt.Println("msg: ", msg) | |||||
| decoder.ProcessIncoming(msg, a.AppState, a.KafkaManager.GetWriter("alertbeacons"), a.ParserRegistry) | decoder.ProcessIncoming(msg, a.AppState, a.KafkaManager.GetWriter("alertbeacons"), a.ParserRegistry) | ||||
| case msg := <-a.ChParser: | case msg := <-a.ChParser: | ||||
| switch msg.ID { | switch msg.ID { | ||||
| @@ -23,11 +23,11 @@ func RunEventLoop(ctx context.Context, a *ServerApp) { | |||||
| case <-ctx.Done(): | case <-ctx.Done(): | ||||
| return | return | ||||
| case msg := <-a.ChHealthLocation: | case msg := <-a.ChHealthLocation: | ||||
| slog.Info("location health", "health", msg) | |||||
| a.AppState.UpdateLocationHealth(msg) | |||||
| case msg := <-a.ChHealthDecoder: | case msg := <-a.ChHealthDecoder: | ||||
| slog.Info("decoder health", "health", msg) | |||||
| a.AppState.UpdateDecoderHealth(msg) | |||||
| case msg := <-a.ChHealthBridge: | case msg := <-a.ChHealthBridge: | ||||
| slog.Info("bridge health", "health", msg) | |||||
| a.AppState.UpdateBridgeHealth(msg) | |||||
| case msg := <-a.ChLoc: | case msg := <-a.ChLoc: | ||||
| switch msg.Method { | switch msg.Method { | ||||
| case "Standard": | case "Standard": | ||||
| @@ -59,6 +59,8 @@ func (a *ServerApp) RegisterRoutes() http.Handler { | |||||
| // Tracks | // Tracks | ||||
| r.HandleFunc("/reslevis/getTracks/{id}", controller.TracksListController(a.DB, a.ctx)).Methods("GET") | r.HandleFunc("/reslevis/getTracks/{id}", controller.TracksListController(a.DB, a.ctx)).Methods("GET") | ||||
| r.HandleFunc("/reslevis/health", controller.HealthController(a.AppState, a.ctx)).Methods("GET") | |||||
| chain := middleware.Recovery(middleware.Logging(middleware.RequestID(middleware.CORS(nil, nil, nil)(r)))) | chain := middleware.Recovery(middleware.Logging(middleware.RequestID(middleware.CORS(nil, nil, nil)(r)))) | ||||
| return chain | return chain | ||||
| } | } | ||||
| @@ -4,6 +4,7 @@ import ( | |||||
| "fmt" | "fmt" | ||||
| "log/slog" | "log/slog" | ||||
| "os" | "os" | ||||
| "sync" | |||||
| "time" | "time" | ||||
| "github.com/AFASystems/presence/internal/pkg/kafkaclient" | "github.com/AFASystems/presence/internal/pkg/kafkaclient" | ||||
| @@ -18,6 +19,7 @@ type AppState struct { | |||||
| beaconsLookup BeaconsLookup | beaconsLookup BeaconsLookup | ||||
| health Health | health Health | ||||
| startTime time.Time | startTime time.Time | ||||
| mu sync.RWMutex | |||||
| } | } | ||||
| func getEnv(key, def string) string { | func getEnv(key, def string) string { | ||||
| @@ -52,7 +54,6 @@ func NewAppState() *AppState { | |||||
| Lookup: make(map[string]string), | Lookup: make(map[string]string), | ||||
| }, | }, | ||||
| health: Health{ | health: Health{ | ||||
| ID: "1", | |||||
| Location: LocationHealth{ | Location: LocationHealth{ | ||||
| BaseHealth: BaseHealth{ | BaseHealth: BaseHealth{ | ||||
| Uptime: 0, | Uptime: 0, | ||||
| @@ -81,6 +82,30 @@ func NewAppState() *AppState { | |||||
| } | } | ||||
| } | } | ||||
| func (m *AppState) GetHealth() Health { | |||||
| m.mu.RLock() | |||||
| defer m.mu.RUnlock() | |||||
| return m.health | |||||
| } | |||||
| func (m *AppState) UpdateLocationHealth(h LocationHealth) { | |||||
| m.mu.Lock() | |||||
| m.health.Location = h | |||||
| m.mu.Unlock() | |||||
| } | |||||
| func (m *AppState) UpdateDecoderHealth(h DecoderHealth) { | |||||
| m.mu.Lock() | |||||
| m.health.Decoder = h | |||||
| m.mu.Unlock() | |||||
| } | |||||
| func (m *AppState) UpdateBridgeHealth(h BridgeHealth) { | |||||
| m.mu.Lock() | |||||
| m.health.Bridge = h | |||||
| m.mu.Unlock() | |||||
| } | |||||
| func (m *AppState) GetLocationHealth(k *kafkaclient.KafkaManager) ([]byte, error) { | func (m *AppState) GetLocationHealth(k *kafkaclient.KafkaManager) ([]byte, error) { | ||||
| m.health.Location.GetUptime(m.startTime) | m.health.Location.GetUptime(m.startTime) | ||||
| m.health.Location.GetActiveReaders(k) | m.health.Location.GetActiveReaders(k) | ||||
| @@ -29,7 +29,6 @@ type BridgeHealth struct { | |||||
| } | } | ||||
| type Health struct { | type Health struct { | ||||
| ID string `json:"id" gorm:"primaryKey"` | |||||
| Location LocationHealth `gorm:"embedded;embeddedPrefix:loc_"` | Location LocationHealth `gorm:"embedded;embeddedPrefix:loc_"` | ||||
| Decoder DecoderHealth `gorm:"embedded;embeddedPrefix:dec_"` | Decoder DecoderHealth `gorm:"embedded;embeddedPrefix:dec_"` | ||||
| Bridge BridgeHealth `gorm:"embedded;embeddedPrefix:brg_"` | Bridge BridgeHealth `gorm:"embedded;embeddedPrefix:brg_"` | ||||
| @@ -1,6 +1,8 @@ | |||||
| package utils | package utils | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "github.com/AFASystems/presence/internal/pkg/common/appcontext" | "github.com/AFASystems/presence/internal/pkg/common/appcontext" | ||||
| "github.com/AFASystems/presence/internal/pkg/model" | "github.com/AFASystems/presence/internal/pkg/model" | ||||
| ) | ) | ||||
| @@ -38,16 +40,18 @@ func RemoveFlagBytes(b []byte) []byte { | |||||
| } | } | ||||
| // Generate event based on the Beacon type | // Generate event based on the Beacon type | ||||
| func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.ParserRegistry) appcontext.BeaconEvent { | |||||
| func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.ParserRegistry, beacon string) appcontext.BeaconEvent { | |||||
| be := appcontext.BeaconEvent{} | be := appcontext.BeaconEvent{} | ||||
| for _, r := range i { | for _, r := range i { | ||||
| ad := b[r[0]:r[1]] | ad := b[r[0]:r[1]] | ||||
| if !isValidADStructure(ad) { | if !isValidADStructure(ad) { | ||||
| fmt.Println("invalid ad structure: ", beacon) | |||||
| break | break | ||||
| } | } | ||||
| for name, parser := range parserRegistry.ParserList { | for name, parser := range parserRegistry.ParserList { | ||||
| if parser.CanParse(ad) { | if parser.CanParse(ad) { | ||||
| event, ok := parser.Parse(name, ad) | event, ok := parser.Parse(name, ad) | ||||
| fmt.Println("parser can parse: ", name) | |||||
| if ok { | if ok { | ||||
| event.ID = id | event.ID = id | ||||
| event.Name = id | event.Name = id | ||||
| @@ -55,6 +59,7 @@ func LoopADStructures(b []byte, i [][2]int, id string, parserRegistry *model.Par | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| // fmt.Println("no parser can parse: ", beacon) | |||||
| } | } | ||||
| return be | return be | ||||
| @@ -26,7 +26,7 @@ func Connect(cfg *config.Config) (*gorm.DB, error) { | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, appcontext.Settings{}, model.Tracks{}, &model.Alert{}, appcontext.Health{}); err != nil { | |||||
| if err := db.AutoMigrate(&model.Gateway{}, model.Zone{}, model.TrackerZones{}, model.Tracker{}, model.Config{}, appcontext.Settings{}, model.Tracks{}, &model.Alert{}); err != nil { | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -30,8 +30,6 @@ func DecodeBeacon(adv appcontext.BeaconAdvertisement, appState *appcontext.AppSt | |||||
| return nil | return nil | ||||
| } | } | ||||
| fmt.Println("beacon: ", beacon) | |||||
| b, err := hex.DecodeString(beacon) | b, err := hex.DecodeString(beacon) | ||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| @@ -39,7 +37,7 @@ func DecodeBeacon(adv appcontext.BeaconAdvertisement, appState *appcontext.AppSt | |||||
| b = utils.RemoveFlagBytes(b) | b = utils.RemoveFlagBytes(b) | ||||
| indices := utils.ParseADFast(b) | indices := utils.ParseADFast(b) | ||||
| event := utils.LoopADStructures(b, indices, id, registry) | |||||
| event := utils.LoopADStructures(b, indices, id, registry, beacon) | |||||
| if event.ID == "" { | if event.ID == "" { | ||||
| return nil | return nil | ||||