diff --git a/go/catalogue/busstate.go b/go/catalogue/busstate.go index 89274d96..1e1040b4 100644 --- a/go/catalogue/busstate.go +++ b/go/catalogue/busstate.go @@ -50,6 +50,9 @@ const ( OptionAgeDays = "max-age-days" // OptionCapMiB is the cap of a stream, a bucket or an object store, in MiB. OptionCapMiB = "max-mib" + // OptionObjectsCapMiB is the cap of a state's objects store `-objects`, in MiB, where the state needs + // another than the one the bus module plans (design 47 G §513, §547). + OptionObjectsCapMiB = "objects-max-mib" // OptionGrant names the trusted config value granting another module a part of it (ADR 0363 §4, ADR 0592 §9). OptionGrant = "grant" // OptionDeliveries is how many times a work queue's message is delivered before it is a dead letter. @@ -142,6 +145,9 @@ type BusStateEntry struct { Configuration map[string]json.RawMessage `json:"configuration,omitempty"` // Types are a ledger's types (ADR 0597 §1), for the storage type ledger only. Types []LedgerType `json:"types,omitempty"` + // Events are the events an entry of the template events carries, named locally, as a part's finding stream + // lists its three finding events; the catalog graph entry carries them (design 47 G §529). + Events []string `json:"events,omitempty"` // KeptLayout is the layout its holder says it writes: its form and its catch-up tool (design 47). KeptLayout } diff --git a/go/catalogue/optional_requirements_test.go b/go/catalogue/optional_requirements_test.go index a48a0aea..d98e8db5 100644 --- a/go/catalogue/optional_requirements_test.go +++ b/go/catalogue/optional_requirements_test.go @@ -81,6 +81,16 @@ func TestARequirementsLongForm(t *testing.T) { // Issue 1966: a key-value entry of `requires` is kept state beside the old section's, by its local name. {"a key-value entry beside an old state", `[{"name":"holds","storage":"key-value","template":"state"}], "state": ["seen"]`, "", []BusStateEntry{{Name: "holds", Storage: StorageKeyValue, Template: TemplateState}}, nil, ""}, + // G §529: a template events entry's field `events` is carried, not set aside; G §513: `objects-max-mib` is a + // state's named option. + {"a finding stream and a state's objects cap", `[{"name":"finding-events","storage":"stream","template":"events", + "options":{"max-age-days":7,"max-mib":16},"events":["finding-written","finding-cleared","findings-stated"]}, + {"name":"findings","storage":"key-value","template":"state","options":{"` + OptionObjectsCapMiB + `":512}}]`, + "", []BusStateEntry{{Name: "finding-events", Storage: StorageStream, Template: TemplateEvents, + Options: map[string]json.RawMessage{"max-age-days": json.RawMessage(`7`), "max-mib": json.RawMessage(`16`)}, + Events: []string{"finding-written", "finding-cleared", "findings-stated"}}, + {Name: "findings", Storage: StorageKeyValue, Template: TemplateState, + Options: map[string]json.RawMessage{"objects-max-mib": json.RawMessage(`512`)}}}, nil, ""}, // A field given twice at any depth is refused, named by its path: a decoder would keep the last without a word. {"a field given twice", `[], "requires": ["postgres-database"]`, "", nil, nil, "the field requires is given twice"}, {"a field given twice deeper", `[{"name":"records","storage":"ledger","name":"other","template":"ledger"}]`, @@ -105,8 +115,11 @@ func TestARequirementsLongForm(t *testing.T) { } // Issue 1966: a ledger is no kept state; KeptStates names the old section's and the key-value entries' alone. var keeps []string - if c.name == "a key-value entry beside an old state" { + switch c.name { + case "a key-value entry beside an old state": keeps = []string{"holds", "seen"} + case "a finding stream and a state's objects cap": + keeps = []string{"findings"} } if kept := KeptStates(got); !reflect.DeepEqual(kept, keeps) { t.Errorf("%s: kept states %v, want %v", c.name, kept, keeps)