package catalogue import ( "bytes" "encoding/json" "fmt" ) // The mesh's bounds on a module's object bucket: its size in MiB (ADR 0592 §5, §25; the bound ADR 0363 §1 sets for a // stream). A bucket says its size: there is no default. const ( ObjectsLeastMiB = 1 ObjectsMostMiB = 8192 ) // FullWarnPercent is how full, in percent of its cap, a history stream or an object bucket is when the mesh raises its // condition, in one place for every module (novox/hq ADR 0592 §6, §25). const FullWarnPercent = 75 // ObjectsDeclaration is one object bucket a module owns. type ObjectsDeclaration struct { // Name is its local name, one plain name as a state's (lower-case letters, digits and hyphens). Name string `json:"name"` // MaxMiB bounds it, ObjectsLeastMiB to ObjectsMostMiB. MaxMiB int `json:"max-mib"` // Grant names the trusted config value of the module whose entries name the modules that may read it; absent, // no other module reads it. Grant *ObjectsGrant `json:"grant,omitempty"` } // ObjectsGrant says which trusted config value of the owning module grants another module the read of a bucket // (novox/hq ADR 0592 §9): the value has a stream grant's shape (GrantedKeys), and a module any of its keys names, wherever // it runs or as `.`, reads the whole bucket, read-only. One value may grant a module's streams and its // object buckets alike. type ObjectsGrant struct { // Config is the trusted config value of the module that grants it (ADR 0348 §8): set only at the controller's // terminal or on the operator's Approve. Config string `json:"config"` } // UnmarshalJSON reads an object bucket strictly: an unknown key is refused here, not passed over. func (o *ObjectsDeclaration) UnmarshalJSON(raw []byte) error { type plain ObjectsDeclaration var p plain dec := json.NewDecoder(bytes.NewReader(raw)) dec.DisallowUnknownFields() if err := dec.Decode(&p); err != nil { return fmt.Errorf("an object bucket is {name, max-mib, grant}: %w", typedUnknown(err)) } *o = ObjectsDeclaration(p) return nil } // UnmarshalJSON reads an object bucket's grant strictly. func (g *ObjectsGrant) UnmarshalJSON(raw []byte) error { type plain ObjectsGrant var p plain dec := json.NewDecoder(bytes.NewReader(raw)) dec.DisallowUnknownFields() if err := dec.Decode(&p); err != nil { return fmt.Errorf("an object bucket's grant is {config}: %w", typedUnknown(err)) } *g = ObjectsGrant(p) return nil } // ObjectsBucket is the bucket's name on the bus, as a state's is: the module and the local name joined by an // underscore, which neither may hold, so two modules never derive one bucket. func ObjectsBucket(module, local string) string { return module + "_" + local } // Bucket is this bucket's name on the bus for its module. func (o ObjectsDeclaration) Bucket(module string) string { return ObjectsBucket(module, o.Name) } // ObjectsNamed is the module's object bucket of the local name, and whether it declares one. func (m Manifest) ObjectsNamed(local string) (ObjectsDeclaration, bool) { for _, o := range m.Objects { if o.Name == local { return o, true } } return ObjectsDeclaration{}, false } // ObjectsReader says whether the restricting config values of a bucket's grant let module, on machine, read it // (novox/hq ADR 0592 §9): a bucket with no grant is read by its owner alone, and a value of another shape grants nothing. func (o ObjectsDeclaration) ObjectsReader(values []any, module, machine string) bool { if o.Grant == nil { return false } for _, v := range values { if len(GrantedKeys(v, module, machine)) > 0 { return true } } return false }