You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by la...@apache.org on 2026/06/23 18:39:09 UTC
(airavata-custos) 01/01: Move audit-trace store into Service dropping AdminDeps
This is an automated email from the ASF dual-hosted git repository.
lahirujayathilake pushed a commit to branch audit-service
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
commit af5914980d85fa4e90ae0ec75990f94e75bf1e3f
Author: lahiruj <la...@gmail.com>
AuthorDate: Tue Jun 23 14:38:58 2026 -0400
Move audit-trace store into Service dropping AdminDeps
---
cmd/server/main.go | 6 +----
internal/server/audit_handlers.go | 9 ++++++--
internal/server/audit_handlers_test.go | 35 ++++++++++++++++--------------
internal/server/integration_common_test.go | 2 +-
internal/server/server.go | 11 ++--------
internal/server/server_trace_test.go | 2 +-
pkg/service/service.go | 11 ++++++++++
7 files changed, 42 insertions(+), 34 deletions(-)
diff --git a/cmd/server/main.go b/cmd/server/main.go
index e7ba08a87..f7cc37762 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -38,7 +38,6 @@ import (
"github.com/apache/airavata-custos/internal/connectors"
"github.com/apache/airavata-custos/internal/db"
"github.com/apache/airavata-custos/internal/server"
- "github.com/apache/airavata-custos/internal/store"
"github.com/apache/airavata-custos/internal/tracing"
"github.com/apache/airavata-custos/pkg/events"
"github.com/apache/airavata-custos/pkg/identity"
@@ -132,11 +131,8 @@ func run() error {
tryBootstrap(ctx, svc)
- adminDeps := &server.AdminDeps{
- AuditTraces: store.NewAuditTraceStore(database),
- }
router := identity.NewRouter(http.NewServeMux())
- srv := server.New(svc, router, adminDeps)
+ srv := server.New(svc, router)
// Tracks every background goroutine spawned by connectors so we can wait
// for them to drain on shutdown instead of killing them mid-flight.
diff --git a/internal/server/audit_handlers.go b/internal/server/audit_handlers.go
index 9b9199c8c..7307df47a 100644
--- a/internal/server/audit_handlers.go
+++ b/internal/server/audit_handlers.go
@@ -39,11 +39,16 @@ const (
)
func (s *Server) requireAuditStore(w http.ResponseWriter) (store.AuditTraceStore, bool) {
- if s.admin == nil || s.admin.AuditTraces == nil {
+ if s.svc == nil {
common.WriteError(w, http.StatusServiceUnavailable, errors.New("audit trace store not configured"))
return nil, false
}
- return s.admin.AuditTraces, true
+ ts := s.svc.AuditTraces()
+ if ts == nil {
+ common.WriteError(w, http.StatusServiceUnavailable, errors.New("audit trace store not configured"))
+ return nil, false
+ }
+ return ts, true
}
// @Summary List audit traces with filters
diff --git a/internal/server/audit_handlers_test.go b/internal/server/audit_handlers_test.go
index d8596320c..7ad3327fc 100644
--- a/internal/server/audit_handlers_test.go
+++ b/internal/server/audit_handlers_test.go
@@ -29,6 +29,7 @@ import (
"github.com/apache/airavata-custos/internal/store"
"github.com/apache/airavata-custos/pkg/identity"
"github.com/apache/airavata-custos/pkg/models"
+ "github.com/apache/airavata-custos/pkg/service"
)
// fakeAuditStore implements AuditTraceStore for handler tests.
@@ -86,12 +87,14 @@ func mustHexTraceID(t *testing.T) string {
return strings.Repeat("ab", 16)
}
-// newAuditServer boots an httptest.Server around the audit handlers with a
-// fake AuditTraceStore. svc is nil, audit handlers don't reach into *Service.
-func newAuditServer(t *testing.T, deps *AdminDeps) *httptest.Server {
+// newAuditServer boots an httptest.Server around the audit handlers with the
+// given fake AuditTraceStore (nil exercises the 503 path).
+func newAuditServer(t *testing.T, audit store.AuditTraceStore) *httptest.Server {
t.Helper()
router := identity.NewRouter(http.NewServeMux())
- inner := New(nil, router, deps)
+ svc := service.New(nil, nil)
+ svc.SetAuditTraces(audit)
+ inner := New(svc, router)
wrap := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
inner.ServeHTTP(w, withTestCaller(r, "test-user"))
})
@@ -114,7 +117,7 @@ func TestListTracesReturnsRowsAndEcho(t *testing.T) {
}},
total: 1,
}
- srv := newAuditServer(t, &AdminDeps{AuditTraces: fs})
+ srv := newAuditServer(t, fs)
resp, err := http.Get(srv.URL + "/audit/traces?source=amie&status=ok&limit=25")
if err != nil {
@@ -148,7 +151,7 @@ func TestListTracesReturnsRowsAndEcho(t *testing.T) {
}
func TestListTracesRejectsBadStatus(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/traces?status=garbage")
if err != nil {
t.Fatalf("get: %v", err)
@@ -161,7 +164,7 @@ func TestListTracesRejectsBadStatus(t *testing.T) {
func TestListTracesAppliesDefaultLimit(t *testing.T) {
fs := &fakeAuditStore{}
- srv := newAuditServer(t, &AdminDeps{AuditTraces: fs})
+ srv := newAuditServer(t, fs)
resp, err := http.Get(srv.URL + "/audit/traces")
if err != nil {
t.Fatalf("get: %v", err)
@@ -177,7 +180,7 @@ func TestListTracesAppliesDefaultLimit(t *testing.T) {
func TestListTracesCapsLimitAt200(t *testing.T) {
fs := &fakeAuditStore{}
- srv := newAuditServer(t, &AdminDeps{AuditTraces: fs})
+ srv := newAuditServer(t, fs)
resp, err := http.Get(srv.URL + "/audit/traces?limit=5000")
if err != nil {
t.Fatalf("get: %v", err)
@@ -189,7 +192,7 @@ func TestListTracesCapsLimitAt200(t *testing.T) {
}
func TestListTracesRejectsOversizeOffset(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/traces?offset=99999999")
if err != nil {
t.Fatalf("get: %v", err)
@@ -201,7 +204,7 @@ func TestListTracesRejectsOversizeOffset(t *testing.T) {
}
func TestListTracesRejectsOversizeWindow(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/traces?from=2024-01-01T00:00:00Z&to=2026-01-02T00:00:00Z")
if err != nil {
t.Fatalf("get: %v", err)
@@ -213,7 +216,7 @@ func TestListTracesRejectsOversizeWindow(t *testing.T) {
}
func TestGetTraceBadHex(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/traces/not-hex")
if err != nil {
t.Fatalf("get: %v", err)
@@ -226,7 +229,7 @@ func TestGetTraceBadHex(t *testing.T) {
func TestGetTraceNotFound(t *testing.T) {
raw := mustHexTraceID(t)
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/traces/" + raw)
if err != nil {
t.Fatalf("get: %v", err)
@@ -268,7 +271,7 @@ func TestGetTraceReturnsTree(t *testing.T) {
},
}
fs := &fakeAuditStore{tree: tree}
- srv := newAuditServer(t, &AdminDeps{AuditTraces: fs})
+ srv := newAuditServer(t, fs)
resp, err := http.Get(srv.URL + "/audit/traces/" + raw)
if err != nil {
@@ -320,7 +323,7 @@ func TestListEventsFlat(t *testing.T) {
Status: "ok",
CreatedAt: time.Unix(1700000000, 0).UTC(),
}}}
- srv := newAuditServer(t, &AdminDeps{AuditTraces: fs})
+ srv := newAuditServer(t, fs)
resp, err := http.Get(srv.URL + "/audit/events?trace_id=" + raw + "&span_id=" + span)
if err != nil {
@@ -351,7 +354,7 @@ func TestListEventsFlat(t *testing.T) {
}
func TestListEventsRejectsMissingTraceID(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/events")
if err != nil {
t.Fatalf("get: %v", err)
@@ -363,7 +366,7 @@ func TestListEventsRejectsMissingTraceID(t *testing.T) {
}
func TestListSources(t *testing.T) {
- srv := newAuditServer(t, &AdminDeps{AuditTraces: &fakeAuditStore{}})
+ srv := newAuditServer(t, &fakeAuditStore{})
resp, err := http.Get(srv.URL + "/audit/sources")
if err != nil {
t.Fatalf("get: %v", err)
diff --git a/internal/server/integration_common_test.go b/internal/server/integration_common_test.go
index d36225331..2bf972f4b 100644
--- a/internal/server/integration_common_test.go
+++ b/internal/server/integration_common_test.go
@@ -72,7 +72,7 @@ func setupTestStack(t *testing.T) (*sqlx.DB, *service.Service, *Server) {
truncateAll(t, sharedDB)
svc := service.New(sharedDB, events.New())
router := identity.NewRouter(http.NewServeMux())
- return sharedDB, svc, New(svc, router, nil)
+ return sharedDB, svc, New(svc, router)
}
func truncateAll(t *testing.T, database *sqlx.DB) {
diff --git a/internal/server/server.go b/internal/server/server.go
index 5b14e56c8..461ae75c5 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -34,23 +34,16 @@ import (
"github.com/apache/airavata-custos/pkg/service"
)
-// AdminDeps wires the /audit/* endpoints. A nil field makes its routes return 503.
-// TODO(server): fold AuditTraces onto *Service and drop AdminDeps.
-type AdminDeps struct {
- AuditTraces store.AuditTraceStore
-}
-
// Server is an HTTP handler that exposes the service API.
type Server struct {
svc *service.Service
router *identity.Router
- admin *AdminDeps
}
// New builds an HTTP handler wired to the supplied service. The router owns the mux
// and gates every authenticated route.
-func New(svc *service.Service, router *identity.Router, admin *AdminDeps) *Server {
- s := &Server{svc: svc, router: router, admin: admin}
+func New(svc *service.Service, router *identity.Router) *Server {
+ s := &Server{svc: svc, router: router}
s.routes()
return s
}
diff --git a/internal/server/server_trace_test.go b/internal/server/server_trace_test.go
index fe50ce8e4..40f86525c 100644
--- a/internal/server/server_trace_test.go
+++ b/internal/server/server_trace_test.go
@@ -41,7 +41,7 @@ func TestLoggingWrapsTracingProducesTraceIdHeader(t *testing.T) {
t.Cleanup(func() { otel.SetTracerProvider(prev) })
router := identity.NewRouter(http.NewServeMux())
- handler := LoggingMiddleware(tracing.Middleware(New(nil, router, nil)))
+ handler := LoggingMiddleware(tracing.Middleware(New(nil, router)))
req := httptest.NewRequest(http.MethodGet, "/healthz", nil)
rec := httptest.NewRecorder()
diff --git a/pkg/service/service.go b/pkg/service/service.go
index c1737d7ab..2c8b42996 100644
--- a/pkg/service/service.go
+++ b/pkg/service/service.go
@@ -57,6 +57,7 @@ type Service struct {
privileges store.UserPrivilegeStore
roles store.RoleStore
userRoles store.UserRoleStore
+ auditTraces store.AuditTraceStore
identityCache *identityCache
}
@@ -87,6 +88,7 @@ func New(database *sqlx.DB, eventBus *events.Bus) *Service {
privileges: store.NewUserPrivilegeStore(database),
roles: store.NewRoleStore(database),
userRoles: store.NewUserRoleStore(database),
+ auditTraces: store.NewAuditTraceStore(database),
identityCache: newIdentityCache(),
}
}
@@ -143,10 +145,19 @@ func NewWithStores(
privileges: privileges,
roles: roles,
userRoles: userRoles,
+ auditTraces: store.NewAuditTraceStore(database),
identityCache: newIdentityCache(),
}
}
+func (s *Service) AuditTraces() store.AuditTraceStore {
+ return s.auditTraces
+}
+
+func (s *Service) SetAuditTraces(ts store.AuditTraceStore) {
+ s.auditTraces = ts
+}
+
// inTx runs fn inside a database transaction managed by the Service.
func (s *Service) inTx(ctx context.Context, fn func(tx *sql.Tx) error) error {
return db.TxFn(ctx, s.db, fn)