dispatch: allow empty route kinds (match all) + add routing tests
- config: permit routes[].kinds to be omitted/empty; treat as "all kinds"
- dispatch: compile empty kinds to Route{Kinds:nil} (match all kinds)
- tests: add coverage for route compilation + config validation edge cases
Files:
- config/load.go
- config/config.go
- dispatch/routes.go
- config/validate_test.go
- dispatch/routes_test.go
This commit is contained in:
@@ -13,11 +13,13 @@ import (
|
||||
// Behavior:
|
||||
// - If cfg.Routes is empty, we default to "all sinks receive all kinds".
|
||||
// (Implemented as one Route per sink with Kinds == nil.)
|
||||
// - If a specific route's kinds: is omitted or empty, that route matches ALL kinds.
|
||||
// (Also compiled as Kinds == nil.)
|
||||
// - Kind strings are normalized via event.ParseKind (lowercase + trim).
|
||||
//
|
||||
// Note: config.Validate() already ensures route.sink references a known sink and
|
||||
// route.kinds are non-empty strings. We re-check a few invariants here anyway so
|
||||
// CompileRoutes is safe to call even if a daemon chooses not to call Validate().
|
||||
// Note: config.Validate() ensures route.sink references a known sink and rejects
|
||||
// blank kind entries. We re-check a few invariants here anyway so CompileRoutes
|
||||
// is safe to call even if a daemon chooses not to call Validate().
|
||||
func CompileRoutes(cfg *config.Config) ([]Route, error) {
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: cfg is nil")
|
||||
@@ -27,14 +29,13 @@ func CompileRoutes(cfg *config.Config) ([]Route, error) {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: cfg has no sinks")
|
||||
}
|
||||
|
||||
// Build a quick lookup of sink names.
|
||||
// Build a quick lookup of sink names (exact match; no normalization).
|
||||
sinkNames := make(map[string]bool, len(cfg.Sinks))
|
||||
for i, s := range cfg.Sinks {
|
||||
name := strings.TrimSpace(s.Name)
|
||||
if name == "" {
|
||||
if strings.TrimSpace(s.Name) == "" {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: sinks[%d].name is empty", i)
|
||||
}
|
||||
sinkNames[name] = true
|
||||
sinkNames[s.Name] = true
|
||||
}
|
||||
|
||||
// Default routing: everything to every sink.
|
||||
@@ -52,16 +53,21 @@ func CompileRoutes(cfg *config.Config) ([]Route, error) {
|
||||
out := make([]Route, 0, len(cfg.Routes))
|
||||
|
||||
for i, r := range cfg.Routes {
|
||||
sink := strings.TrimSpace(r.Sink)
|
||||
if sink == "" {
|
||||
sink := r.Sink
|
||||
if strings.TrimSpace(sink) == "" {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: routes[%d].sink is required", i)
|
||||
}
|
||||
if !sinkNames[sink] {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: routes[%d].sink references unknown sink %q", i, sink)
|
||||
}
|
||||
|
||||
// If kinds is omitted/empty, this route matches all kinds.
|
||||
if len(r.Kinds) == 0 {
|
||||
return nil, fmt.Errorf("dispatch.CompileRoutes: routes[%d].kinds must contain at least one kind", i)
|
||||
out = append(out, Route{
|
||||
SinkName: sink,
|
||||
Kinds: nil,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
kinds := make(map[event.Kind]bool, len(r.Kinds))
|
||||
|
||||
Reference in New Issue
Block a user