Merge pull request 'Registry recovery: mesh-broker's list, show and orphans answer each binding (issue 1966)' (#5) from fix/1966-bindings-first-view into main
This commit was merged in pull request #5.
This commit is contained in:
@@ -72,16 +72,32 @@ const SubjectRecreated = "mesh.seat.mesh-broker.event.recreated"
|
||||
// SubjectDropped is where dropped is published.
|
||||
const SubjectDropped = "mesh.seat.mesh-broker.event.dropped"
|
||||
|
||||
// Binding is the binding a module receives in its membership for one entry (ADR 0595 §1, §7).
|
||||
// Binding is the binding a module receives in its membership for one entry (ADR 0595 §1, §7): the names on the bus of the entry's objects, one form in the events, in list, show and orphans, and in the membership.
|
||||
type Binding struct {
|
||||
// the entry's name on the bus
|
||||
BusName string `json:"bus-name"`
|
||||
// how the bus keeps it
|
||||
StorageType string `json:"storage-type"`
|
||||
// its subjects, for a stream
|
||||
Subjects []string `json:"subjects,omitempty"`
|
||||
// a key-value bucket's name
|
||||
Bucket string `json:"bucket,omitempty"`
|
||||
// a ledger's history stream
|
||||
History string `json:"history,omitempty"`
|
||||
// a ledger's index buckets, by index name
|
||||
Indexes map[string]string `json:"indexes,omitempty"`
|
||||
// the entry's local name in the module's manifest
|
||||
Local string `json:"local"`
|
||||
// an object store's name
|
||||
ObjectStore string `json:"object-store,omitempty"`
|
||||
// the subject of a ledger's instances' snapshots
|
||||
Snapshot string `json:"snapshot,omitempty"`
|
||||
// a ledger's state bucket
|
||||
State string `json:"state,omitempty"`
|
||||
// how the bus keeps it: the entry's storage type
|
||||
Storage string `json:"storage"`
|
||||
// a stream's name on the bus
|
||||
Stream string `json:"stream,omitempty"`
|
||||
// the subject a stream's messages are on; also a ledger's history's
|
||||
Subject string `json:"subject,omitempty"`
|
||||
// its template
|
||||
Template string `json:"template,omitempty"`
|
||||
// a ledger's types, as its manifest declares them
|
||||
Types []map[string]any `json:"types,omitempty"`
|
||||
}
|
||||
|
||||
// Entry is one piece of bus state as a manifest asks it.
|
||||
@@ -131,6 +147,8 @@ type Fill struct {
|
||||
|
||||
// Held is one entry as the bus holds it.
|
||||
type Held struct {
|
||||
// the binding a module receives for the entry, as created and recreated carry it; present on an entry whose objects the bus holds, absent on one it does not (design 25 bindings-first-view §2)
|
||||
Binding *Binding `json:"binding,omitempty"`
|
||||
// its name on the bus, <module>_<local name>
|
||||
BusName string `json:"bus-name"`
|
||||
// its own configuration, where no template fits
|
||||
|
||||
@@ -19,6 +19,8 @@ func TestFixtures(t *testing.T) {
|
||||
}{
|
||||
{name: "created on the seat's subject", subject: "mesh.seat.mesh-broker.event.created", given: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\"}", wire: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\"}",
|
||||
decode: func(b []byte) (any, error) { var v CreatedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.created$")},
|
||||
{name: "created with a ledger's binding as the bus module writes it", subject: "mesh.seat.mesh-broker.event.created", given: "{\"binding\":{\"history\":\"mesh-knowledge_ledger\",\"indexes\":{\"by-kind\":\"mesh-knowledge_ledger_index-by-kind\"},\"local\":\"ledger\",\"snapshot\":\"mesh.ledger.mesh-knowledge.ledger.snapshot\",\"state\":\"mesh-knowledge_ledger_state\",\"storage\":\"ledger\",\"subject\":\"mesh.ledger.mesh-knowledge.ledger.history\",\"template\":\"ledger\",\"types\":[{\"indexes\":[{\"name\":\"by-kind\",\"on\":[\"kind\"]}],\"name\":\"decision\",\"operations\":[{\"effect\":\"set-fields\",\"fields\":[\"title\",\"kind\"],\"name\":\"set\"}],\"schema\":{\"kind\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}}}]},\"bus-name\":\"mesh-knowledge_ledger\",\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"revision\":7,\"storage-type\":\"ledger\",\"template\":\"ledger\"}", wire: "{\"binding\":{\"history\":\"mesh-knowledge_ledger\",\"indexes\":{\"by-kind\":\"mesh-knowledge_ledger_index-by-kind\"},\"local\":\"ledger\",\"snapshot\":\"mesh.ledger.mesh-knowledge.ledger.snapshot\",\"state\":\"mesh-knowledge_ledger_state\",\"storage\":\"ledger\",\"subject\":\"mesh.ledger.mesh-knowledge.ledger.history\",\"template\":\"ledger\",\"types\":[{\"indexes\":[{\"name\":\"by-kind\",\"on\":[\"kind\"]}],\"name\":\"decision\",\"operations\":[{\"effect\":\"set-fields\",\"fields\":[\"title\",\"kind\"],\"name\":\"set\"}],\"schema\":{\"kind\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}}}]},\"bus-name\":\"mesh-knowledge_ledger\",\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"revision\":7,\"storage-type\":\"ledger\",\"template\":\"ledger\"}",
|
||||
decode: func(b []byte) (any, error) { var v CreatedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.created$")},
|
||||
{name: "refused on the seat's subject", subject: "mesh.seat.mesh-broker.event.refused", given: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}", wire: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}",
|
||||
decode: func(b []byte) (any, error) { var v RefusedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-broker\\.event\\.refused$")},
|
||||
{name: "drifted on the seat's subject", subject: "mesh.seat.mesh-broker.event.drifted", given: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}", wire: "{\"asked\":{\"max-mib\":64},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"held\":{\"max-mib\":64},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"storage-type\":\"ledger\",\"template\":\"ledger\",\"why\":\"the bus refused it\"}",
|
||||
@@ -41,6 +43,8 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v DropInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "list answers every entry", subject: "", given: "{\"entries\":[{\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"options\":{\"max-mib\":64},\"settings\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}]}", wire: "{\"entries\":[{\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"options\":{\"max-mib\":64},\"settings\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}]}",
|
||||
decode: func(b []byte) (any, error) { var v ListAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "list answers the binding of an entry the bus holds", subject: "", given: "{\"entries\":[{\"binding\":{\"history\":\"mesh-knowledge_ledger\",\"indexes\":{\"by-kind\":\"mesh-knowledge_ledger_index-by-kind\"},\"local\":\"ledger\",\"snapshot\":\"mesh.ledger.mesh-knowledge.ledger.snapshot\",\"state\":\"mesh-knowledge_ledger_state\",\"storage\":\"ledger\",\"subject\":\"mesh.ledger.mesh-knowledge.ledger.history\",\"template\":\"ledger\",\"types\":[{\"indexes\":[{\"name\":\"by-kind\",\"on\":[\"kind\"]}],\"name\":\"decision\",\"operations\":[{\"effect\":\"set-fields\",\"fields\":[\"title\",\"kind\"],\"name\":\"set\"}],\"schema\":{\"kind\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}}}]},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"settings\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}]}", wire: "{\"entries\":[{\"binding\":{\"history\":\"mesh-knowledge_ledger\",\"indexes\":{\"by-kind\":\"mesh-knowledge_ledger_index-by-kind\"},\"local\":\"ledger\",\"snapshot\":\"mesh.ledger.mesh-knowledge.ledger.snapshot\",\"state\":\"mesh-knowledge_ledger_state\",\"storage\":\"ledger\",\"subject\":\"mesh.ledger.mesh-knowledge.ledger.history\",\"template\":\"ledger\",\"types\":[{\"indexes\":[{\"name\":\"by-kind\",\"on\":[\"kind\"]}],\"name\":\"decision\",\"operations\":[{\"effect\":\"set-fields\",\"fields\":[\"title\",\"kind\"],\"name\":\"set\"}],\"schema\":{\"kind\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"}}}]},\"bus-name\":\"mesh-knowledge_ledger\",\"fill\":{\"bytes\":2048,\"cap\":67108864,\"count\":10},\"local-name\":\"ledger\",\"module\":\"mesh-knowledge\",\"settings\":{\"max-mib\":64},\"storage-type\":\"ledger\",\"template\":\"ledger\"}]}",
|
||||
decode: func(b []byte) (any, error) { var v ListAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
@@ -22,6 +22,62 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "created with a ledger's binding as the bus module writes it",
|
||||
"of": "event:created",
|
||||
"subject": "mesh.seat.mesh-broker.event.created",
|
||||
"given": {
|
||||
"module": "mesh-knowledge",
|
||||
"local-name": "ledger",
|
||||
"storage-type": "ledger",
|
||||
"template": "ledger",
|
||||
"bus-name": "mesh-knowledge_ledger",
|
||||
"binding": {
|
||||
"local": "ledger",
|
||||
"storage": "ledger",
|
||||
"template": "ledger",
|
||||
"subject": "mesh.ledger.mesh-knowledge.ledger.history",
|
||||
"history": "mesh-knowledge_ledger",
|
||||
"state": "mesh-knowledge_ledger_state",
|
||||
"indexes": {
|
||||
"by-kind": "mesh-knowledge_ledger_index-by-kind"
|
||||
},
|
||||
"snapshot": "mesh.ledger.mesh-knowledge.ledger.snapshot",
|
||||
"types": [
|
||||
{
|
||||
"name": "decision",
|
||||
"schema": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "set",
|
||||
"effect": "set-fields",
|
||||
"fields": [
|
||||
"title",
|
||||
"kind"
|
||||
]
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"name": "by-kind",
|
||||
"on": [
|
||||
"kind"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"revision": 7
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "refused on the seat's subject",
|
||||
"of": "event:refused",
|
||||
|
||||
@@ -47,5 +47,71 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "list answers the binding of an entry the bus holds",
|
||||
"of": "verb:list.answer",
|
||||
"given": {
|
||||
"entries": [
|
||||
{
|
||||
"module": "mesh-knowledge",
|
||||
"local-name": "ledger",
|
||||
"storage-type": "ledger",
|
||||
"template": "ledger",
|
||||
"bus-name": "mesh-knowledge_ledger",
|
||||
"settings": {
|
||||
"max-mib": 64
|
||||
},
|
||||
"fill": {
|
||||
"count": 10,
|
||||
"bytes": 2048,
|
||||
"cap": 67108864
|
||||
},
|
||||
"binding": {
|
||||
"local": "ledger",
|
||||
"storage": "ledger",
|
||||
"template": "ledger",
|
||||
"subject": "mesh.ledger.mesh-knowledge.ledger.history",
|
||||
"history": "mesh-knowledge_ledger",
|
||||
"state": "mesh-knowledge_ledger_state",
|
||||
"indexes": {
|
||||
"by-kind": "mesh-knowledge_ledger_index-by-kind"
|
||||
},
|
||||
"snapshot": "mesh.ledger.mesh-knowledge.ledger.snapshot",
|
||||
"types": [
|
||||
{
|
||||
"name": "decision",
|
||||
"schema": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"operations": [
|
||||
{
|
||||
"name": "set",
|
||||
"effect": "set-fields",
|
||||
"fields": [
|
||||
"title",
|
||||
"kind"
|
||||
]
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
{
|
||||
"name": "by-kind",
|
||||
"on": [
|
||||
"kind"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+50
-11
@@ -403,6 +403,10 @@
|
||||
"why": {
|
||||
"type": "string",
|
||||
"description": "why it is in its state, in plain words; empty when held as asked"
|
||||
},
|
||||
"binding": {
|
||||
"$ref": "#/defs/Binding",
|
||||
"description": "the binding a module receives for the entry, as created and recreated carry it; present on an entry whose objects the bus holds, absent on one it does not (design 25 bindings-first-view §2)"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -540,31 +544,66 @@
|
||||
"Binding": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bus-name": {
|
||||
"local": {
|
||||
"type": "string",
|
||||
"description": "the entry's name on the bus"
|
||||
"description": "the entry's local name in the module's manifest"
|
||||
},
|
||||
"storage-type": {
|
||||
"storage": {
|
||||
"type": "string",
|
||||
"description": "how the bus keeps it"
|
||||
"description": "how the bus keeps it: the entry's storage type"
|
||||
},
|
||||
"template": {
|
||||
"type": "string",
|
||||
"description": "its template"
|
||||
},
|
||||
"subjects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"stream": {
|
||||
"type": "string",
|
||||
"description": "a stream's name on the bus"
|
||||
},
|
||||
"subject": {
|
||||
"type": "string",
|
||||
"description": "the subject a stream's messages are on; also a ledger's history's"
|
||||
},
|
||||
"bucket": {
|
||||
"type": "string",
|
||||
"description": "a key-value bucket's name"
|
||||
},
|
||||
"object-store": {
|
||||
"type": "string",
|
||||
"description": "an object store's name"
|
||||
},
|
||||
"history": {
|
||||
"type": "string",
|
||||
"description": "a ledger's history stream"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"description": "a ledger's state bucket"
|
||||
},
|
||||
"indexes": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "its subjects, for a stream"
|
||||
"description": "a ledger's index buckets, by index name"
|
||||
},
|
||||
"snapshot": {
|
||||
"type": "string",
|
||||
"description": "the subject of a ledger's instances' snapshots"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "a ledger's types, as its manifest declares them"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"bus-name",
|
||||
"storage-type"
|
||||
"local",
|
||||
"storage"
|
||||
],
|
||||
"description": "the binding a module receives in its membership for one entry (ADR 0595 §1, §7)"
|
||||
"description": "the binding a module receives in its membership for one entry (ADR 0595 §1, §7): the names on the bus of the entry's objects, one form in the events, in list, show and orphans, and in the membership"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,16 +47,32 @@ export const recreatedSubject = "mesh.seat.mesh-broker.event.recreated";
|
||||
|
||||
export const droppedSubject = "mesh.seat.mesh-broker.event.dropped";
|
||||
|
||||
/** the binding a module receives in its membership for one entry (ADR 0595 §1, §7) */
|
||||
/** the binding a module receives in its membership for one entry (ADR 0595 §1, §7): the names on the bus of the entry's objects, one form in the events, in list, show and orphans, and in the membership */
|
||||
export interface Binding {
|
||||
/** the entry's name on the bus */
|
||||
"bus-name": string;
|
||||
/** how the bus keeps it */
|
||||
"storage-type": string;
|
||||
/** its subjects, for a stream */
|
||||
"subjects"?: string[];
|
||||
/** a key-value bucket's name */
|
||||
"bucket"?: string;
|
||||
/** a ledger's history stream */
|
||||
"history"?: string;
|
||||
/** a ledger's index buckets, by index name */
|
||||
"indexes"?: Record<string, string>;
|
||||
/** the entry's local name in the module's manifest */
|
||||
"local": string;
|
||||
/** an object store's name */
|
||||
"object-store"?: string;
|
||||
/** the subject of a ledger's instances' snapshots */
|
||||
"snapshot"?: string;
|
||||
/** a ledger's state bucket */
|
||||
"state"?: string;
|
||||
/** how the bus keeps it: the entry's storage type */
|
||||
"storage": string;
|
||||
/** a stream's name on the bus */
|
||||
"stream"?: string;
|
||||
/** the subject a stream's messages are on; also a ledger's history's */
|
||||
"subject"?: string;
|
||||
/** its template */
|
||||
"template"?: string;
|
||||
/** a ledger's types, as its manifest declares them */
|
||||
"types"?: Record<string, unknown>[];
|
||||
}
|
||||
|
||||
/** one piece of bus state as a manifest asks it */
|
||||
@@ -86,6 +102,8 @@ export interface Fill {
|
||||
|
||||
/** one entry as the bus holds it */
|
||||
export interface Held {
|
||||
/** the binding a module receives for the entry, as created and recreated carry it; present on an entry whose objects the bus holds, absent on one it does not (design 25 bindings-first-view §2) */
|
||||
"binding"?: Binding;
|
||||
/** its name on the bus, <module>_<local name> */
|
||||
"bus-name": string;
|
||||
/** its own configuration, where no template fits */
|
||||
|
||||
Reference in New Issue
Block a user