Neues Paket mail/internal/healthcheck: Checker sammelt benannte CheckFunc-Prüfungen, liefert Gesamt- und Einzelstatus je Komponente (ok/degraded, nie ein generischer Fehler). Fehlertexte einzelner Prüfungen fließen nie in die HTTP-Antwort — nur Name+Status je Komponente. Vier konkrete Prüfungen (checks.go) gegen die real vorhandenen Ticket-Abhängigkeiten: DatabaseCheck (pgxpool.Ping), ObjectStorageCheck (HeadBucket gegen den ARC-06-Bucket), SearchIndexCheck (reale Manticore-Anfrage), JobQueueCheck (COUNT gegen mail_index_jobs, SRC-02/indexworker — COUNT statt Zeilenzugriff, damit eine leere aber erreichbare Queue nicht fälschlich als Ausfall gilt). RegisterRoutes registriert GET /api/v1/mail/health ohne Authentifizierung auf einem vom Aufrufer bereitgestellten *http.ServeMux, gleiches Pfadschema wie mailapi (INT-01) — Core API-01 hat weiterhin keinen abrufbaren Router. Alle drei Pflichtprüfungen mit echten Nachweisen: simulierter Ausfall einer von vier Abhängigkeiten korrekt als degraded abgebildet, eine Prüfung mit absichtlich eingebetteter Verbindungszeichenfolge inkl. Passwort im Fehlertext taucht nirgends in der HTTP-Antwort auf, echter httptest-HTTP-Server-Integrationstest gegen den Endpunkt. Alle vier konkreten Prüfungen zusätzlich real gegen laufende Postgres-, MinIO- und Manticore-Instanzen verifiziert (inkl. echter ARC-06-Provisionierung). go build/go vet/golangci-lint clean, gesamtes Mail-Modul regressionsfrei getestet.
57 lines
1.9 KiB
Go
57 lines
1.9 KiB
Go
package healthcheck
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
|
|
"gitea.perlbach24.de/scripte/nexarch/mail/internal/search"
|
|
)
|
|
|
|
// DatabaseCheck prüft die Erreichbarkeit der Tenant-Postgres-Datenbank
|
|
// (Akzeptanzkriterium 1: Datenbank).
|
|
func DatabaseCheck(pool *pgxpool.Pool) CheckFunc {
|
|
return func(ctx context.Context) error {
|
|
return pool.Ping(ctx)
|
|
}
|
|
}
|
|
|
|
// ObjectStorageCheck prüft die Erreichbarkeit des mandantenspezifischen
|
|
// Objekt-Storage-Buckets (ARC-06) — Akzeptanzkriterium 1:
|
|
// Objektspeicher.
|
|
func ObjectStorageCheck(s3Admin *s3.Client, bucket string) CheckFunc {
|
|
return func(ctx context.Context) error {
|
|
_, err := s3Admin.HeadBucket(ctx, &s3.HeadBucketInput{Bucket: aws.String(bucket)})
|
|
return err
|
|
}
|
|
}
|
|
|
|
// SearchIndexCheck prüft die Erreichbarkeit des Manticore-Suchindex
|
|
// (SRC-01) — Akzeptanzkriterium 1: Suchindex. Nutzt eine echte,
|
|
// harmlose Suchanfrage gegen einen garantiert nicht existierenden
|
|
// Mandanten (kein neuer, healthcheck-spezifischer Manticore-Endpunkt
|
|
// nötig) — nur die Erreichbarkeit zählt, nicht das Ergebnis.
|
|
func SearchIndexCheck(client *search.Client) CheckFunc {
|
|
return func(ctx context.Context) error {
|
|
_, err := client.Search(ctx, "healthcheck-probe-kein-echter-mandant", "")
|
|
return err
|
|
}
|
|
}
|
|
|
|
// JobQueueCheck prüft die Erreichbarkeit der Postgres-Jobqueue
|
|
// (SRC-02, mail_index_jobs) — Akzeptanzkriterium 1: Jobqueue. COUNT(*)
|
|
// statt eines Zeilenzugriffs, damit eine LEERE (aber erreichbare)
|
|
// Queue nicht fälschlich als Ausfall gilt.
|
|
func JobQueueCheck(pool *pgxpool.Pool) CheckFunc {
|
|
return func(ctx context.Context) error {
|
|
var count int64
|
|
if err := pool.QueryRow(ctx, "SELECT count(*) FROM mail_index_jobs").Scan(&count); err != nil {
|
|
return fmt.Errorf("healthcheck: jobqueue: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
}
|