|
|
|
@@ -9,6 +9,7 @@ import ( |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
"github.com/AFASystems/presence/internal/pkg/config" |
|
|
|
"github.com/AFASystems/presence/internal/pkg/kafkaclient" |
|
|
|
"github.com/AFASystems/presence/internal/pkg/model" |
|
|
|
"github.com/gorilla/handlers" |
|
|
|
@@ -27,20 +28,71 @@ func main() { |
|
|
|
} |
|
|
|
|
|
|
|
func HttpServer(addr string) { |
|
|
|
cfg := config.Load() |
|
|
|
|
|
|
|
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With"}) |
|
|
|
originsOk := handlers.AllowedOrigins([]string{"*"}) |
|
|
|
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS"}) |
|
|
|
|
|
|
|
// Kafka writer that relays messages |
|
|
|
writer := kafkaclient.KafkaWriter("127.0.0.1:9092", "apibeacons") |
|
|
|
writer := kafkaclient.KafkaWriter(cfg.KafkaURL, "apibeacons") |
|
|
|
defer writer.Close() |
|
|
|
|
|
|
|
settingsWriter := kafkaclient.KafkaWriter("kafka:9092", "settings") |
|
|
|
settingsWriter := kafkaclient.KafkaWriter(cfg.KafkaURL, "settings") |
|
|
|
defer settingsWriter.Close() |
|
|
|
|
|
|
|
// Define if maybe ws writer should have more topics |
|
|
|
wsWriter := kafkaclient.KafkaWriter("kafka:9092", "wsmessages") |
|
|
|
defer wsWriter.Close() |
|
|
|
// Kafka reader for Raw MQTT beacons |
|
|
|
locationReader := kafkaclient.KafkaReader(cfg.KafkaURL, "locevents", "gid-loc-serv") |
|
|
|
defer locationReader.Close() |
|
|
|
|
|
|
|
// Kafka reader for API server updates |
|
|
|
alertsReader := kafkaclient.KafkaReader(cfg.KafkaURL, "alertbeacons", "gid-alert-serv") |
|
|
|
defer alertsReader.Close() |
|
|
|
|
|
|
|
client := redis.NewClient(&redis.Options{ |
|
|
|
Addr: "127.0.0.1:6379", |
|
|
|
Password: "", |
|
|
|
}) |
|
|
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
|
|
|
// Separate channel for location change? |
|
|
|
chLoc := make(chan model.HTTPLocation, 200) |
|
|
|
chEvents := make(chan model.BeaconEvent, 500) |
|
|
|
|
|
|
|
go kafkaclient.Consume(locationReader, chLoc) |
|
|
|
go kafkaclient.Consume(alertsReader, chEvents) |
|
|
|
|
|
|
|
go func() { |
|
|
|
for { |
|
|
|
select { |
|
|
|
case msg := <-chLoc: |
|
|
|
key := fmt.Sprintf("beacon:%s", msg.ID) |
|
|
|
hashM, err := msg.RedisHashable() |
|
|
|
if err != nil { |
|
|
|
fmt.Println("Error in converting location into hashmap for Redis insert: ", err) |
|
|
|
continue |
|
|
|
} |
|
|
|
err = client.HSet(ctx, key, hashM).Err() |
|
|
|
if err != nil { |
|
|
|
fmt.Println("Error in persisting set in Redis key: ", key) |
|
|
|
continue |
|
|
|
} |
|
|
|
case msg := <-chEvents: |
|
|
|
key := fmt.Sprintf("beacon:%s", msg.ID) |
|
|
|
hashM, err := msg.RedisHashable() |
|
|
|
if err != nil { |
|
|
|
fmt.Println("Error in converting location into hashmap for Redis insert: ", err) |
|
|
|
continue |
|
|
|
} |
|
|
|
err = client.HSet(ctx, key, hashM).Err() |
|
|
|
if err != nil { |
|
|
|
fmt.Println("Error in persisting set in Redis key: ", key) |
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}() |
|
|
|
|
|
|
|
r := mux.NewRouter() |
|
|
|
|
|
|
|
@@ -53,7 +105,7 @@ func HttpServer(addr string) { |
|
|
|
|
|
|
|
// For now just add beacon DELETE / GET / POST / PUT methods |
|
|
|
r.HandleFunc("/api/beacons/{beacon_id}", beaconsDeleteHandler(writer)).Methods("DELETE") |
|
|
|
// r.HandleFunc("/api/beacons", beaconsListHandler(client)).Methods("GET") |
|
|
|
r.HandleFunc("/api/beacons/{beacon_id}", beaconsListHandler(ctx, client)).Methods("GET") |
|
|
|
r.HandleFunc("/api/beacons", beaconsAddHandler(writer)).Methods("POST") |
|
|
|
r.HandleFunc("/api/beacons", beaconsAddHandler(writer)).Methods("PUT") |
|
|
|
|
|
|
|
@@ -69,6 +121,30 @@ func HttpServer(addr string) { |
|
|
|
http.ListenAndServe(addr, handlers.CORS(originsOk, headersOk, methodsOk)(r)) |
|
|
|
} |
|
|
|
|
|
|
|
func beaconsListHandler(ctx context.Context, client *redis.Client) http.HandlerFunc { |
|
|
|
return func(w http.ResponseWriter, r *http.Request) { |
|
|
|
vars := mux.Vars(r) |
|
|
|
id := vars["beacon_id"] |
|
|
|
key := fmt.Sprintf("beacon:%s", id) |
|
|
|
beacon, err := client.HGetAll(ctx, key).Result() |
|
|
|
if err != nil { |
|
|
|
res := fmt.Sprintf("Error in getting beacon data (key: %s), error: %v", key, err) |
|
|
|
fmt.Println(res) |
|
|
|
http.Error(w, res, 500) |
|
|
|
} |
|
|
|
|
|
|
|
fmt.Printf("%+v", beacon) |
|
|
|
rData, err := json.Marshal(beacon) |
|
|
|
if err != nil { |
|
|
|
res := fmt.Sprintf("Error in marshaling beacon data (key: %s), error: %v", key, err) |
|
|
|
fmt.Println(res) |
|
|
|
http.Error(w, res, 500) |
|
|
|
} |
|
|
|
|
|
|
|
w.Write(rData) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Probably define value as interface and then reuse this writer in all of the functions |
|
|
|
func sendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate) bool { |
|
|
|
valueStr, err := json.Marshal(&value) |
|
|
|
@@ -145,15 +221,6 @@ func beaconsAddHandler(writer *kafka.Writer) http.HandlerFunc { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// func beaconsListHandler(client *redis.Client) http.HandlerFunc { |
|
|
|
// return func(w http.ResponseWriter, r *http.Request) { |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
// func settingsListHandler(client *redis.Client) http.HandlerFunc { |
|
|
|
// return func(w http.ResponseWriter, r *http.Request) {} |
|
|
|
// } |
|
|
|
|
|
|
|
func settingsEditHandler(writer *kafka.Writer) http.HandlerFunc { |
|
|
|
return func(w http.ResponseWriter, r *http.Request) { |
|
|
|
decoder := json.NewDecoder(r.Body) |
|
|
|
|