package controller import ( "context" "encoding/json" "fmt" "net/http" "github.com/AFASystems/presence/internal/pkg/common/appcontext" "github.com/AFASystems/presence/internal/pkg/model" "github.com/gorilla/mux" "github.com/segmentio/kafka-go" ) func GetBeaconIds(appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { beacons := appstate.GetAllHttpResults() bIds := make([]string, len(beacons)) i := 0 for k := range beacons { bIds[i] = k i++ } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(bIds) } } func BeaconsListSingleController(appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["beacon_id"] beacon, ok := appstate.GetHTTPResult(id) if !ok { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) json.NewEncoder(w).Encode(map[string]string{"error": "Beacon not found"}) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(beacon) } } func BeaconsListController(appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { beacons := appstate.GetAllHttpResults() values := make([]model.HTTPResult, len(beacons)) i := 0 for k, v := range beacons { if k == "" { continue } values[i] = v i++ } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(values) } } // Probably define value as interface and then reuse this writer in all of the functions func sendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate, ctx context.Context) error { valueStr, err := json.Marshal(&value) if err != nil { fmt.Println("error in encoding: ", err) return err } msg := kafka.Message{ Value: valueStr, } if err := writer.WriteMessages(ctx, msg); err != nil { fmt.Println("Error in sending kafka message: ", err) return err } return nil } func BeaconsDeleteController(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) beaconId := vars["beacon_id"] apiUpdate := model.ApiUpdate{ Method: "DELETE", ID: beaconId, } fmt.Printf("Sending DELETE beacon id: %s message\n", beaconId) if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { fmt.Println("error in sending Kafka DELETE message") http.Error(w, "Error in sending kafka message", 500) return } // If message is succesfully sent delete the beacon from the list appstate.RemoveHTTPResult(beaconId) w.Write([]byte("ok")) } } func BeaconAddService(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState, beacon model.HTTPResult) error { id := beacon.ID appstate.UpdateHTTPResult(id, beacon) apiUpdate := model.ApiUpdate{ Method: "POST", Beacon: beacon, } if err := sendKafkaMessage(writer, &apiUpdate, ctx); err != nil { return err } return nil } func BeaconsAddController(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var inBeacon model.HTTPResult err := decoder.Decode(&inBeacon) if err != nil { http.Error(w, err.Error(), 400) return } if inBeacon.ID == "" { http.Error(w, "Beacon needs to include MAC addr", 400) return } if err := BeaconAddService(writer, ctx, appstate, inBeacon); err != nil { fmt.Println("error in sending Kafka POST message") http.Error(w, "Error in sending kafka message", 500) return } w.Write([]byte("ok")) } } func AddListOfBeaconsController(writer *kafka.Writer, ctx context.Context, appstate *appcontext.AppState) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) var inBeacons []model.HTTPResult if err := decoder.Decode(&inBeacons); err != nil { http.Error(w, err.Error(), 400) return } for _, v := range inBeacons { if v.ID == "" { fmt.Println("One of the beacons is missing MAC address") http.Error(w, "One of the beacons is missing MAC address", 400) return } if err := BeaconAddService(writer, ctx, appstate, v); err != nil { fmt.Println("error in sending Kafka POST message") http.Error(w, "Error in sending kafka message", 500) return } } w.Write([]byte("ok")) } }