|
|
|
@@ -0,0 +1,127 @@ |
|
|
|
package main |
|
|
|
|
|
|
|
import ( |
|
|
|
"context" |
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"net/http" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
"github.com/AFASystems/presence/internal/pkg/model" |
|
|
|
"github.com/gorilla/handlers" |
|
|
|
"github.com/gorilla/mux" |
|
|
|
"github.com/redis/go-redis/v9" |
|
|
|
"github.com/segmentio/kafka-go" |
|
|
|
) |
|
|
|
|
|
|
|
func main() { |
|
|
|
HttpServer("127.0.0.1:1902") |
|
|
|
} |
|
|
|
|
|
|
|
func HttpServer(addr string) { |
|
|
|
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 := kafkaWriter("127.0.0.1:9092", "apibeacons") |
|
|
|
defer writer.Close() |
|
|
|
|
|
|
|
r := mux.NewRouter() |
|
|
|
|
|
|
|
client := redis.NewClient(&redis.Options{ |
|
|
|
Addr: "127.0.0.1:6379", |
|
|
|
Password: "", |
|
|
|
}) |
|
|
|
|
|
|
|
// 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", beaconsAddHandler(writer)).Methods("POST") |
|
|
|
r.HandleFunc("/api/beacons", beaconsAddHandler(writer)).Methods("PUT") |
|
|
|
http.ListenAndServe(addr, handlers.CORS(originsOk, headersOk, methodsOk)(r)) |
|
|
|
} |
|
|
|
|
|
|
|
// All the functions should do is just relay messages to the decoder through Kafka |
|
|
|
|
|
|
|
func kafkaWriter(kafkaURL, topic string) *kafka.Writer { |
|
|
|
return &kafka.Writer{ |
|
|
|
Addr: kafka.TCP(kafkaURL), |
|
|
|
Topic: topic, |
|
|
|
Balancer: &kafka.LeastBytes{}, |
|
|
|
BatchSize: 100, |
|
|
|
BatchTimeout: 10 * time.Millisecond, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func sendKafkaMessage(writer *kafka.Writer, value *model.ApiUpdate) { |
|
|
|
valueStr, err := json.Marshal(&value) |
|
|
|
if err != nil { |
|
|
|
fmt.Println("error in encoding: ", err) |
|
|
|
} |
|
|
|
msg := kafka.Message{ |
|
|
|
Value: valueStr, |
|
|
|
} |
|
|
|
|
|
|
|
err = writer.WriteMessages(context.Background(), msg) |
|
|
|
if err != nil { |
|
|
|
fmt.Println("Error in sending kafka message: ") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func beaconsDeleteHandler(writer *kafka.Writer) 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, |
|
|
|
} |
|
|
|
|
|
|
|
sendKafkaMessage(writer, &apiUpdate) |
|
|
|
w.Write([]byte("ok")) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func beaconsAddHandler(writer *kafka.Writer) http.HandlerFunc { |
|
|
|
return func(w http.ResponseWriter, r *http.Request) { |
|
|
|
decoder := json.NewDecoder(r.Body) |
|
|
|
var inBeacon model.Beacon |
|
|
|
err := decoder.Decode(&inBeacon) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
http.Error(w, err.Error(), 400) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (len(strings.TrimSpace(inBeacon.Name)) == 0) || (len(strings.TrimSpace(inBeacon.Beacon_id)) == 0) { |
|
|
|
http.Error(w, "name and beacon_id cannot be blank", 400) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
apiUpdate := model.ApiUpdate{ |
|
|
|
Method: "POST", |
|
|
|
Beacon: inBeacon, |
|
|
|
} |
|
|
|
|
|
|
|
sendKafkaMessage(writer, &apiUpdate) |
|
|
|
|
|
|
|
w.Write([]byte("ok")) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
func beaconsListHandler(client *redis.Client) http.HandlerFunc { |
|
|
|
return func(w http.ResponseWriter, r *http.Request) { |
|
|
|
beaconsList, err := client.Get(context.Background(), "beaconsList").Result() |
|
|
|
if err == redis.Nil { |
|
|
|
fmt.Println("no beacons list, starting empty") |
|
|
|
http.Error(w, "list is empty", 500) |
|
|
|
} else if err != nil { |
|
|
|
http.Error(w, "Internal server error", 500) |
|
|
|
panic(err) |
|
|
|
} else { |
|
|
|
w.Write([]byte(beaconsList)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |