Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,45 @@ The format is based on [Keep a Changelog], and this project adheres to
[semantic versioning]: https://semver.org/spec/v2.0.0.html
[bc]: https://github.com/dogmatiq/.github/blob/main/VERSIONING.md#changelogs

## [Unreleased]

This release moves Dogma's Protocol Buffers schema to the
[`github.com/dogmatiq/protobuf`] module. The `uuidpb`, `identitypb`,
`envelopepb` and `messaginggrpc` packages are now provided by that module, and
`configpb` is regenerated to import its types.

The schema in `github.com/dogmatiq/protobuf` uses the `dogma.protobuf.v1`
Protocol Buffers package instead of `dogma.protobuf`, so the full names of
these messages and their `google.protobuf.Any` type URLs have changed. Their
binary encoding is unchanged.

### Added

- Added the `envelope` package, which contains `Packer`, `EffectPacker`,
`Unpack()` and the packing options previously in `envelopepb`.
- Added the `uuidcollection` package, which contains `Map`, `Set` and
`NewSet()` previously in `uuidpb`.

### Changed

- **[BC]** `envelope.WithExtension()` and `WithBaggage()` now panic if the
value is a nil pointer, such as `(*wrapperspb.StringValue)(nil)`. Previously,
it was packed as an empty message.

### Removed

- **[BC]** Removed the `protobuf/uuidpb`, `protobuf/identitypb` and
`protobuf/envelopepb` packages. Use the packages of the same name in
`github.com/dogmatiq/protobuf` instead.
- **[BC]** Removed the `grpc/messaginggrpc` package. Use the package of the same
name in `github.com/dogmatiq/protobuf` instead.
- **[BC]** Removed `CommandExecutorAPI` and the `UnrecognizedApplication`,
`UnrecognizedCommandType`, `UnrecognizedEventType`, `MalformedMessage` and
`InvalidMessage` error details, along with their error constructors. They're
expected in a future version of `github.com/dogmatiq/protobuf`.

[`github.com/dogmatiq/protobuf`]: https://github.com/dogmatiq/protobuf

## [0.28.0] - 2026-11-02

### Added
Expand Down
2 changes: 1 addition & 1 deletion config/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package config
import (
"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/protobuf/identitypb"
)

// Aggregate is a [Handler] that represents the configuration of a
Expand Down
4 changes: 2 additions & 2 deletions config/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (

"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/identitypb"
"github.com/dogmatiq/protobuf/uuidpb"
)

// Application is an [Entity] that represents the configuration of a
Expand Down
4 changes: 2 additions & 2 deletions config/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

"github.com/dogmatiq/enginekit/internal/typename"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/identitypb"
"github.com/dogmatiq/protobuf/uuidpb"
)

// An Entity is a [Component] that that represents the configuration of a Dogma
Expand Down
4 changes: 2 additions & 2 deletions config/entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/dogmatiq/enginekit/config/internal/configbuilder"
"github.com/dogmatiq/enginekit/config/internal/constraints"
"github.com/dogmatiq/enginekit/internal/test"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/identitypb"
"github.com/dogmatiq/protobuf/uuidpb"
)

func testEntity[
Expand Down
2 changes: 1 addition & 1 deletion config/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"unicode"

"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/uuidpb"
)

// Identity is a [Component] that that represents the unique identity of an
Expand Down
2 changes: 1 addition & 1 deletion config/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package config
import (
"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/protobuf/identitypb"
)

// Integration is a [Handler] that represents the configuration of a
Expand Down
2 changes: 1 addition & 1 deletion config/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package config
import (
"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/protobuf/identitypb"
)

// Process is a [Handler] that represents the configuration of a
Expand Down
2 changes: 1 addition & 1 deletion config/projection.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package config
import (
"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/optional"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/protobuf/identitypb"
)

// Projection is a [Handler] that represents the configuration of a
Expand Down
2 changes: 1 addition & 1 deletion enginetest/stubs/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"regexp"

"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/uuidpb"
)

// CommandStub is a test implementation of [dogma.Command].
Expand Down
2 changes: 1 addition & 1 deletion enginetest/stubs/uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"strconv"
"sync/atomic"

"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/uuidpb"
)

// UUIDSequence is a generator of deterministic UUIDs for use in tests.
Expand Down
19 changes: 19 additions & 0 deletions envelope/any.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package envelope

import (
"github.com/dogmatiq/protobuf/envelopepb"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/anypb"
)

// packAsAny returns x as an [*anypb.Any], panicking if it is nil or cannot be
// packed.
//
// Options pack their value when they are created, rather than when they are
// applied, so that an invalid value is reported where the option is created and
// is packed only once.
func packAsAny(x proto.Message) *anypb.Any {
body := &envelopepb.Body{}
envelopepb.SetExtension(body, x)
return body.GetExtensions()[0]
}
2 changes: 2 additions & 0 deletions envelope/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package envelope packs Dogma messages into envelopes and unpacks them again.
package envelope
47 changes: 24 additions & 23 deletions protobuf/envelopepb/effectpacker.go → envelope/effectpacker.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
package envelopepb
package envelope

import (
"fmt"

"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
"github.com/dogmatiq/protobuf/envelopepb"
"github.com/dogmatiq/protobuf/identitypb"
"github.com/dogmatiq/protobuf/uuidpb"
"google.golang.org/protobuf/types/known/timestamppb"
)

// An EffectPacker packs messages produced while handling a specific causal
// message into a [MultiEnvelope].
// message into a [envelopepb.MultiEnvelope].
type EffectPacker struct {
generateID func() *uuidpb.UUID
now func() *timestamppb.Timestamp
header *Header
bodies []*Body
header *envelopepb.Header
bodies []*envelopepb.Body
sealed bool
}

// PackEffects returns an [EffectPacker] that packs messages produced by h while
// handling cause.
func (p *Packer) PackEffects(
cause *Envelope,
cause *envelopepb.Envelope,
h *identitypb.Identity,
options ...PackEffectsOption,
) *EffectPacker {
Expand Down Expand Up @@ -51,10 +52,10 @@ func (p *Packer) PackEffects(
}
}

header := NewHeaderBuilder().
header := envelopepb.NewHeaderBuilder().
WithCausationId(cause.GetBody().GetMessageId()).
WithCorrelationId(cause.GetHeader().GetCorrelationId()).
WithSource(NewSourceBuilder().
WithSource(envelopepb.NewSourceBuilder().
WithSite(p.Site).
WithApplication(p.Application).
WithHandler(h).
Expand All @@ -69,7 +70,7 @@ func (p *Packer) PackEffects(
opt.applyPackEffectsOption(header)
}

if err := header.validate(); err != nil {
if err := header.Validate(); err != nil {
panic(fmt.Errorf("invalid header: %w", err))
}

Expand All @@ -81,26 +82,26 @@ func (p *Packer) PackEffects(
}

// PackCommand appends m to the multi-envelope under construction.
func (p *EffectPacker) PackCommand(m dogma.Command, options ...PackEffectCommandOption) *Envelope {
func (p *EffectPacker) PackCommand(m dogma.Command, options ...PackEffectCommandOption) *envelopepb.Envelope {
return packEffectBody(p, m, PackEffectCommandOption.applyPackEffectCommandOption, options...)
}

// PackEvent appends m to the multi-envelope under construction.
func (p *EffectPacker) PackEvent(m dogma.Event, options ...PackEffectEventOption) *Envelope {
func (p *EffectPacker) PackEvent(m dogma.Event, options ...PackEffectEventOption) *envelopepb.Envelope {
return packEffectBody(p, m, PackEffectEventOption.applyPackEffectEventOption, options...)
}

// PackDeadline appends m to the multi-envelope under construction.
func (p *EffectPacker) PackDeadline(m dogma.Deadline, options ...PackEffectDeadlineOption) *Envelope {
func (p *EffectPacker) PackDeadline(m dogma.Deadline, options ...PackEffectDeadlineOption) *envelopepb.Envelope {
return packEffectBody(p, m, PackEffectDeadlineOption.applyPackEffectDeadlineOption, options...)
}

func packEffectBody[T any](
p *EffectPacker,
m dogma.Message,
apply func(T, *Body),
apply func(T, *envelopepb.Body),
options ...T,
) *Envelope {
) *envelopepb.Envelope {
p.mustNotBeSealed()

mt, ok := dogma.RegisteredMessageTypeOf(m)
Expand All @@ -120,10 +121,10 @@ func packEffectBody[T any](
))
}

body := NewBodyBuilder().
body := envelopepb.NewBodyBuilder().
WithMessageId(p.generateID()).
WithMessage(
NewMessageBuilder().
envelopepb.NewMessageBuilder().
WithTypeId(uuidpb.MustParse(mt.ID())).
WithDescription(m.MessageDescription()).
WithData(data).
Expand All @@ -139,29 +140,29 @@ func packEffectBody[T any](
body.SetCreatedAt(p.now())
}

if err := body.validate(p.header); err != nil {
if err := body.Validate(p.header); err != nil {
panic(fmt.Errorf("invalid body: %w", err))
}

p.bodies = append(p.bodies, body)

return NewEnvelopeBuilder().
return envelopepb.NewEnvelopeBuilder().
WithHeader(p.header).
WithBody(body).
Build()
}

// Seal returns a [MultiEnvelope] containing all packed messages, or false if no
// messages were packed.
func (p *EffectPacker) Seal() (*MultiEnvelope, bool) {
// Seal returns a [envelopepb.MultiEnvelope] containing all packed messages, or
// false if no messages were packed.
func (p *EffectPacker) Seal() (*envelopepb.MultiEnvelope, bool) {
p.mustNotBeSealed()
p.sealed = true

if len(p.bodies) == 0 {
return nil, false
}

return NewMultiEnvelopeBuilder().
return envelopepb.NewMultiEnvelopeBuilder().
WithHeader(p.header).
WithBodies(p.bodies).
Build(), true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package envelopepb_test
package envelope_test

import (
"testing"
"time"

. "github.com/dogmatiq/enginekit/enginetest/stubs"
. "github.com/dogmatiq/enginekit/envelope"
. "github.com/dogmatiq/enginekit/internal/test"
. "github.com/dogmatiq/enginekit/protobuf/envelopepb"
"github.com/dogmatiq/enginekit/protobuf/identitypb"
"github.com/dogmatiq/enginekit/protobuf/uuidpb"
. "github.com/dogmatiq/protobuf/envelopepb"
"github.com/dogmatiq/protobuf/identitypb"
"github.com/dogmatiq/protobuf/uuidpb"
anypb "google.golang.org/protobuf/types/known/anypb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
Expand Down
Loading
Loading