package main import ( "encoding/json" "errors" "io" "log/slog" "net/http" "os" "strconv" "strings" "sync" "time" ) const maxCallbackBodyBytes = 1 << 20 type collector struct { mu sync.Mutex deliveries int64 duplicates int64 invalid int64 seen map[string]int } func main() { address := strings.TrimSpace(os.Getenv("HTTP_ADDR")) if address == "" { address = ":8091" } state := &collector{seen: map[string]int{}} mux := http.NewServeMux() mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) { writeJSON(w, http.StatusOK, map[string]any{"ok": true}) }) mux.HandleFunc("GET /report", state.report) mux.HandleFunc("POST /callbacks", state.callback) server := &http.Server{ Addr: address, Handler: mux, ReadHeaderTimeout: 10 * time.Second, } slog.Info("acceptance callback collector started", "address", address) if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { slog.Error("acceptance callback collector stopped", "error", err) os.Exit(1) } } func (c *collector) callback(w http.ResponseWriter, request *http.Request) { body, err := io.ReadAll(io.LimitReader(request.Body, maxCallbackBodyBytes+1)) if err != nil || len(body) > maxCallbackBodyBytes { c.recordInvalid() writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid callback body"}) return } decoder := json.NewDecoder(strings.NewReader(string(body))) decoder.UseNumber() var payload map[string]any if err := decoder.Decode(&payload); err != nil { c.recordInvalid() writeJSON(w, http.StatusBadRequest, map[string]any{"error": "invalid callback JSON"}) return } taskID := strings.TrimSpace(stringValue(payload["taskId"])) seq, _ := strconv.ParseInt(stringValue(payload["seq"]), 10, 64) idempotency := strings.TrimSpace(request.Header.Get("Idempotency-Key")) expected := taskID + ":" + strconv.FormatInt(seq, 10) if taskID == "" || seq <= 0 || idempotency != expected { c.recordInvalid() writeJSON(w, http.StatusBadRequest, map[string]any{"error": "callback identity is invalid"}) return } c.mu.Lock() c.deliveries++ c.seen[expected]++ if c.seen[expected] > 1 { c.duplicates++ } c.mu.Unlock() writeJSON(w, http.StatusOK, map[string]any{"ok": true}) } func (c *collector) report(w http.ResponseWriter, _ *http.Request) { c.mu.Lock() report := map[string]any{ "schemaVersion": "acceptance-callback-report/v1", "deliveries": c.deliveries, "duplicates": c.duplicates, "invalid": c.invalid, "uniqueEvents": len(c.seen), } c.mu.Unlock() writeJSON(w, http.StatusOK, report) } func (c *collector) recordInvalid() { c.mu.Lock() c.invalid++ c.mu.Unlock() } func stringValue(value any) string { switch typed := value.(type) { case string: return typed case json.Number: return typed.String() case float64: return strconv.FormatFloat(typed, 'f', -1, 64) default: return "" } } func writeJSON(w http.ResponseWriter, status int, value any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _ = json.NewEncoder(w).Encode(value) }