From e9410af74b15ea6af655610d116247c67009225d Mon Sep 17 00:00:00 2001 From: Max Ekman Date: Mon, 21 Dec 2020 20:48:40 +0100 Subject: [PATCH] Add CommandIDer and FromCommand event option --- command.go | 6 ++++++ event.go | 13 +++++++++++++ event_test.go | 28 +++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/command.go b/command.go index 54b6eae4..635c9991 100644 --- a/command.go +++ b/command.go @@ -53,6 +53,12 @@ func (ct CommandType) String() string { return string(ct) } +// CommandIDer provides a unique command ID to be used for request tracking etc. +type CommandIDer interface { + // CommandID returns the ID of the command instance being handled. + CommandID() uuid.UUID +} + // ErrCommandNotRegistered is when no command factory was registered. var ErrCommandNotRegistered = errors.New("command not registered") diff --git a/event.go b/event.go index db67617e..d0038647 100644 --- a/event.go +++ b/event.go @@ -96,6 +96,19 @@ func WithMetadata(metadata map[string]interface{}) EventOption { } } +// FromCommand adds metadat for the originating command when crating an event. +// Currently it adds the command type and optionally a command ID (if the +// CommandIDer interface is implemented). +func FromCommand(cmd Command) EventOption { + md := map[string]interface{}{ + "command_type": cmd.CommandType().String(), + } + if c, ok := cmd.(CommandIDer); ok { + md["command_id"] = c.CommandID().String() + } + return WithMetadata(md) +} + // NewEvent creates a new event with a type and data, setting its timestamp. func NewEvent(eventType EventType, data EventData, timestamp time.Time, options ...EventOption) Event { e := &event{ diff --git a/event_test.go b/event_test.go index 1398166e..9bc2a5ad 100644 --- a/event_test.go +++ b/event_test.go @@ -42,8 +42,14 @@ func TestNewEvent(t *testing.T) { } id := uuid.New() + cmd := TestCommandID{ + TestID: id, + Content: "content", + CmdID: uuid.New(), + } event = NewEvent(TestEventType, &TestEventData{"event1"}, timestamp, ForAggregate(TestAggregateType, id, 3), + FromCommand(cmd), WithMetadata(map[string]interface{}{"meta": "data", "num": 42}), ) if event.EventType() != TestEventType { @@ -64,7 +70,12 @@ func TestNewEvent(t *testing.T) { if event.Version() != 3 { t.Error("the version should be zero:", event.Version()) } - if !reflect.DeepEqual(event.Metadata(), map[string]interface{}{"meta": "data", "num": 42}) { + if !reflect.DeepEqual(event.Metadata(), map[string]interface{}{ + "meta": "data", + "num": 42, + "command_type": cmd.CommandType().String(), + "command_id": cmd.CmdID.String(), + }) { t.Error("the metadata should be correct:", event.Metadata()) } if event.String() != "TestEvent@3" { @@ -160,3 +171,18 @@ type TestEventRegisterEmptyData struct{} type TestEventRegisterTwiceData struct{} type TestEventUnregisterTwiceData struct{} + +type TestCommandID struct { + TestID uuid.UUID + Content string + CmdID uuid.UUID +} + +var _ = Command(TestCommandID{}) + +func (t TestCommandID) AggregateID() uuid.UUID { return t.TestID } +func (t TestCommandID) AggregateType() AggregateType { return TestAggregateType } +func (t TestCommandID) CommandType() CommandType { + return CommandType("TestCommandID") +} +func (t TestCommandID) CommandID() uuid.UUID { return t.CmdID }