refactor: migrate eventsourced to codeberg and go-messaging-amqp #949
No files matched your search
@@ -9,7 +9,7 @@ This is a GraphQL schema registry service that manages federated GraphQL schemas
|
||||
## Architecture
|
||||
|
||||
### Event Sourcing
|
||||
The system uses event sourcing via `gitlab.com/unboundsoftware/eventsourced`. Key domain aggregates are:
|
||||
The system uses event sourcing via `codeberg.org/eventsourced`. Key domain aggregates are:
|
||||
- **Organization** (domain/aggregates.go): Manages organizations, users, and API keys
|
||||
- **SubGraph** (domain/aggregates.go): Tracks subgraph schemas with versioning
|
||||
|
||||
|
||||
Vendored
+3
-4
@@ -6,8 +6,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sparetimecoders/goamqp"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/graph/model"
|
||||
@@ -133,7 +132,7 @@ func (c *Cache) SubGraphId(orgId, ref, service string) string {
|
||||
return c.subGraphs[subGraphKey(orgId, ref, service)]
|
||||
}
|
||||
|
||||
func (c *Cache) Update(msg any, _ goamqp.Headers) (any, error) {
|
||||
func (c *Cache) Update(msg any) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
@@ -250,7 +249,7 @@ func (c *Cache) Update(msg any, _ goamqp.Headers) (any, error) {
|
||||
default:
|
||||
c.logger.With("msg", msg).Warn("unexpected message received")
|
||||
}
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cache) updateSubGraph(orgId string, ref string, subGraphId string, service string, updated time.Time) {
|
||||
|
||||
Vendored
+10
-10
@@ -7,10 +7,10 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/hash"
|
||||
@@ -208,7 +208,7 @@ func TestCache_Update_OrganizationAdded(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify organization was added
|
||||
@@ -247,7 +247,7 @@ func TestCache_Update_APIKeyAdded(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(uuid.New().String())
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify API key was added to cache
|
||||
@@ -281,7 +281,7 @@ func TestCache_Update_SubGraphUpdated(t *testing.T) {
|
||||
event.ID = *eventsourced.IdFromString(subGraphID)
|
||||
event.SetWhen(time.Now())
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify subgraph was added to services
|
||||
@@ -366,7 +366,7 @@ func TestCache_ConcurrentWrites(t *testing.T) {
|
||||
Initiator: "user-" + string(rune(index)),
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
assert.NoError(t, err)
|
||||
}(i)
|
||||
}
|
||||
@@ -423,7 +423,7 @@ func TestCache_ConcurrentReadsAndWrites(t *testing.T) {
|
||||
Initiator: "user-new-" + string(rune(index)),
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(newOrgID)
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
assert.NoError(t, err)
|
||||
}(i)
|
||||
}
|
||||
@@ -471,7 +471,7 @@ func TestCache_Update_APIKeyRemoved(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify API key was removed from cache
|
||||
@@ -523,7 +523,7 @@ func TestCache_Update_APIKeyRemoved_MultipleKeys(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify only key2 was removed
|
||||
@@ -579,7 +579,7 @@ func TestCache_Update_OrganizationRemoved(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify organization was removed
|
||||
@@ -633,7 +633,7 @@ func TestCache_Update_OrganizationRemoved_MultipleUsers(t *testing.T) {
|
||||
}
|
||||
event.ID = *eventsourced.IdFromString(orgID)
|
||||
|
||||
_, err := c.Update(event, nil)
|
||||
err := c.Update(event)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify user1 still has otherOrgID but not removed orgID
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"testing"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
goamqp "codeberg.org/messaging/go-messaging-amqp"
|
||||
spec "codeberg.org/messaging/messaging"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/cache"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
)
|
||||
|
||||
// ownKeys is a literal list on purpose: deriving it from the code would keep a renamed key green.
|
||||
var ownKeys = []string{
|
||||
"SubGraph.Updated",
|
||||
"Organization.Added",
|
||||
"Organization.UserAdded",
|
||||
"Organization.APIKeyAdded",
|
||||
"Organization.APIKeyRemoved",
|
||||
"Organization.Removed",
|
||||
}
|
||||
|
||||
func Test_amqpSetups(t *testing.T) {
|
||||
setups := amqpSetups(slog.Default(), make(chan error, 1), goamqp.NewPublisher(), cache.New(slog.Default()))
|
||||
topology, err := goamqp.CollectTopology(serviceName, setups...)
|
||||
require.NoError(t, err)
|
||||
|
||||
var consumed, publishesTo []string
|
||||
for _, e := range topology.Endpoints {
|
||||
switch e.Direction {
|
||||
case spec.DirectionConsume:
|
||||
assert.True(t, e.Ephemeral, "cache consumers must be transient, %s is durable", e.QueueName)
|
||||
consumed = append(consumed, e.RoutingKey)
|
||||
case spec.DirectionPublish:
|
||||
publishesTo = append(publishesTo, e.ExchangeName)
|
||||
}
|
||||
}
|
||||
assert.ElementsMatch(t, ownKeys, consumed)
|
||||
assert.Equal(t, []string{"events.topic.exchange"}, publishesTo)
|
||||
}
|
||||
|
||||
type recordingPublisher struct {
|
||||
keys []string
|
||||
ctxs []context.Context
|
||||
}
|
||||
|
||||
func (r *recordingPublisher) Publish(ctx context.Context, routingKey string, _ any, _ ...goamqp.Header) error {
|
||||
r.keys = append(r.keys, routingKey)
|
||||
r.ctxs = append(r.ctxs, ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_newEventPublisher(t *testing.T) {
|
||||
rec := &recordingPublisher{}
|
||||
p, err := newEventPublisher(rec)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, e := range []eventsourced.Event{
|
||||
&domain.SubGraphUpdated{},
|
||||
&domain.OrganizationAdded{},
|
||||
&domain.UserAddedToOrganization{},
|
||||
&domain.APIKeyAdded{},
|
||||
&domain.APIKeyRemoved{},
|
||||
&domain.OrganizationRemoved{},
|
||||
} {
|
||||
require.NoError(t, p.Publish(context.Background(), e))
|
||||
}
|
||||
assert.Equal(t, ownKeys, rec.keys, "published keys must match what the cache consumers bind")
|
||||
}
|
||||
|
||||
func Test_uncancelledPublisher(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
rec := &recordingPublisher{}
|
||||
p, err := newEventPublisher(uncancelledPublisher{rec})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, p.Publish(ctx, &domain.OrganizationAdded{}))
|
||||
assert.NoError(t, rec.ctxs[0].Err(), "publish must not see the request's cancellation")
|
||||
}
|
||||
+61
-32
@@ -13,6 +13,11 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"codeberg.org/eventsourced/amqp"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/pg/v2"
|
||||
goamqp "codeberg.org/messaging/go-messaging-amqp"
|
||||
spec "codeberg.org/messaging/messaging"
|
||||
"github.com/99designs/gqlgen/graphql/handler"
|
||||
"github.com/99designs/gqlgen/graphql/handler/extension"
|
||||
"github.com/99designs/gqlgen/graphql/handler/lru"
|
||||
@@ -20,11 +25,7 @@ import (
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/alecthomas/kong"
|
||||
"github.com/rs/cors"
|
||||
"github.com/sparetimecoders/goamqp"
|
||||
"github.com/vektah/gqlparser/v2/ast"
|
||||
"gitlab.com/unboundsoftware/eventsourced/amqp"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"gitlab.com/unboundsoftware/eventsourced/pg/v2"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/cache"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
@@ -57,7 +58,8 @@ func main() {
|
||||
var cli CLI
|
||||
_ = kong.Parse(&cli)
|
||||
logger := logging.SetupLogger(cli.LogLevel, cli.LogFormat, serviceName, buildVersion)
|
||||
closeEvents := make(chan error)
|
||||
// buffered: go-messaging-amqp reports a lost connection without blocking
|
||||
closeEvents := make(chan error, 1)
|
||||
|
||||
if err := start(
|
||||
closeEvents,
|
||||
@@ -114,7 +116,7 @@ func start(closeEvents chan error, logger *slog.Logger, connectToAmqpFunc func(u
|
||||
}
|
||||
|
||||
publisher := goamqp.NewPublisher()
|
||||
eventPublisher, err := amqp.New(publisher)
|
||||
eventPublisher, err := newEventPublisher(uncancelledPublisher{publisher})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create event publisher: %v", err)
|
||||
}
|
||||
@@ -130,25 +132,7 @@ func start(closeEvents chan error, logger *slog.Logger, connectToAmqpFunc func(u
|
||||
if err := loadSubGraphs(rootCtx, eventStore, serviceCache); err != nil {
|
||||
return fmt.Errorf("caching subgraphs: %w", err)
|
||||
}
|
||||
setups := []goamqp.Setup{
|
||||
goamqp.UseLogger(func(s string) { logger.Error(s) }),
|
||||
goamqp.CloseListener(closeEvents),
|
||||
goamqp.WithPrefetchLimit(20),
|
||||
goamqp.EventStreamPublisher(publisher),
|
||||
goamqp.TransientEventStreamConsumer("SubGraph.Updated", serviceCache.Update, domain.SubGraphUpdated{}),
|
||||
goamqp.TransientEventStreamConsumer("Organization.Added", serviceCache.Update, domain.OrganizationAdded{}),
|
||||
goamqp.TransientEventStreamConsumer("Organization.UserAdded", serviceCache.Update, domain.UserAddedToOrganization{}),
|
||||
goamqp.TransientEventStreamConsumer("Organization.APIKeyAdded", serviceCache.Update, domain.APIKeyAdded{}),
|
||||
goamqp.TransientEventStreamConsumer("Organization.APIKeyRemoved", serviceCache.Update, domain.APIKeyRemoved{}),
|
||||
goamqp.TransientEventStreamConsumer("Organization.Removed", serviceCache.Update, domain.OrganizationRemoved{}),
|
||||
goamqp.WithTypeMapping("SubGraph.Updated", domain.SubGraphUpdated{}),
|
||||
goamqp.WithTypeMapping("Organization.Added", domain.OrganizationAdded{}),
|
||||
goamqp.WithTypeMapping("Organization.UserAdded", domain.UserAddedToOrganization{}),
|
||||
goamqp.WithTypeMapping("Organization.APIKeyAdded", domain.APIKeyAdded{}),
|
||||
goamqp.WithTypeMapping("Organization.APIKeyRemoved", domain.APIKeyRemoved{}),
|
||||
goamqp.WithTypeMapping("Organization.Removed", domain.OrganizationRemoved{}),
|
||||
}
|
||||
if err := conn.Start(rootCtx, setups...); err != nil {
|
||||
if err := conn.Start(rootCtx, amqpSetups(logger, closeEvents, publisher, serviceCache)...); err != nil {
|
||||
return fmt.Errorf("failed to setup AMQP: %v", err)
|
||||
}
|
||||
|
||||
@@ -181,10 +165,13 @@ func start(closeEvents chan error, logger *slog.Logger, connectToAmqpFunc func(u
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err := <-closeEvents
|
||||
if err != nil {
|
||||
logger.With("error", err).Error("received close from AMQP")
|
||||
rootCancel()
|
||||
select {
|
||||
case err := <-closeEvents:
|
||||
if err != nil {
|
||||
logger.With("error", err).Error("received close from AMQP")
|
||||
rootCancel()
|
||||
}
|
||||
case <-rootCtx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -200,7 +187,6 @@ func start(closeEvents chan error, logger *slog.Logger, connectToAmqpFunc func(u
|
||||
logger.With("error", err).Error("close http server")
|
||||
}
|
||||
close(sigint)
|
||||
close(closeEvents)
|
||||
}()
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
@@ -300,7 +286,7 @@ func loadOrganizations(ctx context.Context, eventStore eventsourced.EventStore,
|
||||
if _, err := eventsourced.NewHandler(ctx, organization, eventStore); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := serviceCache.Update(organization, nil)
|
||||
err := serviceCache.Update(organization)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -318,7 +304,7 @@ func loadSubGraphs(ctx context.Context, eventStore eventsourced.EventStore, serv
|
||||
if _, err := eventsourced.NewHandler(ctx, subGraph, eventStore); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := serviceCache.Update(subGraph, nil)
|
||||
err := serviceCache.Update(subGraph)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -326,6 +312,49 @@ func loadSubGraphs(ctx context.Context, eventStore eventsourced.EventStore, serv
|
||||
return nil
|
||||
}
|
||||
|
||||
func newEventPublisher(p amqp.BackingPublisher) (*amqp.Amqp, error) {
|
||||
return amqp.New(
|
||||
p,
|
||||
amqp.WithTypeMapping("SubGraph.Updated", domain.SubGraphUpdated{}),
|
||||
amqp.WithTypeMapping("Organization.Added", domain.OrganizationAdded{}),
|
||||
amqp.WithTypeMapping("Organization.UserAdded", domain.UserAddedToOrganization{}),
|
||||
amqp.WithTypeMapping("Organization.APIKeyAdded", domain.APIKeyAdded{}),
|
||||
amqp.WithTypeMapping("Organization.APIKeyRemoved", domain.APIKeyRemoved{}),
|
||||
amqp.WithTypeMapping("Organization.Removed", domain.OrganizationRemoved{}),
|
||||
)
|
||||
}
|
||||
|
||||
func amqpSetups(logger *slog.Logger, closeEvents chan error, publisher *goamqp.Publisher, serviceCache *cache.Cache) []goamqp.Setup {
|
||||
return []goamqp.Setup{
|
||||
goamqp.WithLogger(logger),
|
||||
goamqp.CloseListener(closeEvents),
|
||||
goamqp.EventStreamPublisher(publisher),
|
||||
goamqp.TransientEventStreamConsumer("SubGraph.Updated", cacheUpdater[domain.SubGraphUpdated](serviceCache)),
|
||||
goamqp.TransientEventStreamConsumer("Organization.Added", cacheUpdater[domain.OrganizationAdded](serviceCache)),
|
||||
goamqp.TransientEventStreamConsumer("Organization.UserAdded", cacheUpdater[domain.UserAddedToOrganization](serviceCache)),
|
||||
goamqp.TransientEventStreamConsumer("Organization.APIKeyAdded", cacheUpdater[domain.APIKeyAdded](serviceCache)),
|
||||
goamqp.TransientEventStreamConsumer("Organization.APIKeyRemoved", cacheUpdater[domain.APIKeyRemoved](serviceCache)),
|
||||
goamqp.TransientEventStreamConsumer("Organization.Removed", cacheUpdater[domain.OrganizationRemoved](serviceCache)),
|
||||
}
|
||||
}
|
||||
|
||||
// uncancelledPublisher detaches publishes from the request context: eventsourced publishes
|
||||
// right after storing an event, and a stored event must be published even if the client left.
|
||||
type uncancelledPublisher struct {
|
||||
amqp.BackingPublisher
|
||||
}
|
||||
|
||||
func (p uncancelledPublisher) Publish(ctx context.Context, routingKey string, msg any, headers ...goamqp.Header) error {
|
||||
return p.BackingPublisher.Publish(context.WithoutCancel(ctx), routingKey, msg, headers...)
|
||||
}
|
||||
|
||||
// cacheUpdater passes the payload as a pointer, which is what Cache.Update switches on
|
||||
func cacheUpdater[T any](c *cache.Cache) spec.EventHandler[T] {
|
||||
return func(_ context.Context, e spec.ConsumableEvent[T]) error {
|
||||
return c.Update(&e.Payload)
|
||||
}
|
||||
}
|
||||
|
||||
func ConnectAMQP(url string) (Connection, error) {
|
||||
return goamqp.NewFromURL(serviceName, url)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/hash"
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
)
|
||||
|
||||
type Organization struct {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/hash"
|
||||
)
|
||||
|
||||
@@ -5,9 +5,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/hash"
|
||||
)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package domain
|
||||
|
||||
import "gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
import "codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
type OrganizationAdded struct {
|
||||
eventsourced.BaseEvent
|
||||
|
||||
@@ -4,9 +4,9 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
)
|
||||
|
||||
func TestOrganizationAdded_UpdateOrganization(t *testing.T) {
|
||||
|
||||
@@ -3,6 +3,11 @@ module gitea.unbound.se/unboundsoftware/schemas
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
codeberg.org/eventsourced/amqp v1.10.1
|
||||
codeberg.org/eventsourced/eventsourced v1.24.0
|
||||
codeberg.org/eventsourced/pg/v2 v2.1.1
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5
|
||||
codeberg.org/messaging/messaging v0.0.5
|
||||
github.com/99designs/gqlgen v0.17.95
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||
github.com/Khan/genqlient v0.8.1
|
||||
@@ -13,13 +18,9 @@ require (
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/pressly/goose/v3 v3.28.0
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/sparetimecoders/goamqp v0.3.3
|
||||
github.com/stretchr/testify v1.12.1
|
||||
github.com/vektah/gqlparser/v2 v2.5.37
|
||||
github.com/wundergraph/graphql-go-tools/v2 v2.20.3
|
||||
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1
|
||||
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.23.0
|
||||
gitlab.com/unboundsoftware/eventsourced/pg/v2 v2.0.2
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1
|
||||
go.opentelemetry.io/otel v1.46.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.46.0
|
||||
@@ -37,6 +38,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/agnivade/levenshtein v1.2.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/buger/jsonparser v1.1.2 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
@@ -58,8 +60,13 @@ require (
|
||||
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
|
||||
github.com/lib/pq v1.12.3 // indirect
|
||||
github.com/mfridman/interpolate v0.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.22.0 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.15.0 // indirect
|
||||
github.com/segmentio/asm v1.2.1 // indirect
|
||||
github.com/sethvargo/go-retry v0.4.0 // indirect
|
||||
github.com/sosodev/duration v1.4.0 // indirect
|
||||
@@ -77,6 +84,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.46.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.5 // indirect
|
||||
golang.org/x/mod v0.41.0 // indirect
|
||||
golang.org/x/net v0.58.0 // indirect
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
codeberg.org/eventsourced/amqp v1.10.1 h1:nGSG+lKbq8ibr7p8WBqSfH12uROQb+UXKg6BFnhquY4=
|
||||
codeberg.org/eventsourced/amqp v1.10.1/go.mod h1:qQLe1a9T56hrPc/lxtoXWTqU3fnsgulQ1j4luQLNpcg=
|
||||
codeberg.org/eventsourced/eventsourced v1.24.0 h1:yNB+74JNB/NHo7D8ZR/yQcTVDYrWnjFf0xUKLgViqRc=
|
||||
codeberg.org/eventsourced/eventsourced v1.24.0/go.mod h1:uy0HxejDdNFpI+Yp7VOEvjfEUFJQX1VkCZ4e4JyDp7Q=
|
||||
codeberg.org/eventsourced/pg/v2 v2.1.1 h1:4OHmMU7v93mXUY0ldfz18lkqDC7UGCtDee4wMLIi43I=
|
||||
codeberg.org/eventsourced/pg/v2 v2.1.1/go.mod h1:y/3Rul9NTcq7ScL5Z44cdDQrrOk6drrudGLoUYjrIns=
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5 h1:zzcJ+FVWgBPKyTkq9RXF11yvnhs8IN5BALBC+mps1zA=
|
||||
codeberg.org/messaging/go-messaging-amqp v0.0.5/go.mod h1:6bSCIkKH0V/oI7vaIq8ttINKYwov9c8ckZrwjfvp7kc=
|
||||
codeberg.org/messaging/messaging v0.0.5 h1:/ueH90F4RNPUeeJIwdG9oVhDW7+XjCzwOYq8xc0kfQk=
|
||||
codeberg.org/messaging/messaging v0.0.5/go.mod h1:xyWLUcfaVzcN6GWk9uaQsxPVUC2Vm2S89mYZGdiWTWg=
|
||||
codeberg.org/messaging/messaging/tck v0.0.3 h1:a4Nr7ytFqEJloTOyVeAtMNgO9Fig1ZUirjW4FVlK0lc=
|
||||
codeberg.org/messaging/messaging/tck v0.0.3/go.mod h1:RiOsKXGAhNQK2STBVYGjhN0CFtmcrsEne1qUe15n8Q4=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
||||
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
||||
@@ -26,6 +38,8 @@ github.com/auth0/go-jwt-middleware/v3 v3.3.0 h1:nRALRLGsUdWgxX0knqwp60YxiYypeZYf
|
||||
github.com/auth0/go-jwt-middleware/v3 v3.3.0/go.mod h1:WXL/zFf3nuQJWQOVj3hGUQ289ixKVSrFGwZn6LxaQsw=
|
||||
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk=
|
||||
github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
@@ -84,6 +98,8 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||
github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8=
|
||||
github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -119,6 +135,14 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
|
||||
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
|
||||
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
|
||||
github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
|
||||
github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4=
|
||||
github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs=
|
||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -131,8 +155,16 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pressly/goose/v3 v3.28.0 h1:D2M+iL31GmpZxSHOhX8mqyqAT3CXnokUmm0eKoSP+Vc=
|
||||
github.com/pressly/goose/v3 v3.28.0/go.mod h1:v26MOuB8bL3kzzrt3Vqhb3R0PRVsl8hFQKdrht/L6Rk=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.22.0 h1:6q9+/JL9IKAPbCmBrv9n5O5Ty3NKnciV5X7YGw0oics=
|
||||
github.com/prometheus/procfs v0.22.0/go.mod h1:CvmFr/GVhIjIvWJZW3tgkODBQMRIf0EyWMQLHCHab58=
|
||||
github.com/rabbitmq/amqp091-go v1.15.0 h1:LEQL4/yp48/Wigt6A6XOu18RQRo8ZHtB5I/KZJn+gkw=
|
||||
github.com/rabbitmq/amqp091-go v1.15.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@@ -156,8 +188,6 @@ github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h
|
||||
github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs=
|
||||
github.com/sosodev/duration v1.4.0 h1:35ed0KiVFriGHHzZZJaZLgmTEEICIyt8Sx0RQfj9IjE=
|
||||
github.com/sosodev/duration v1.4.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
|
||||
github.com/sparetimecoders/goamqp v0.3.3 h1:z/nfTPmrjeU/rIVuNOgsVLCimp3WFoNFvS3ZzXRJ6HE=
|
||||
github.com/sparetimecoders/goamqp v0.3.3/go.mod h1:W9NRCpWLE+Vruv2dcRSbszNil2O826d2Nv6kAkETW5o=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
|
||||
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
|
||||
@@ -195,12 +225,6 @@ github.com/wundergraph/go-arena v1.3.0 h1:n0ng5a1vbd8YGq1u3rMr0vPU5f6AZ1BXIiUhL1
|
||||
github.com/wundergraph/go-arena v1.3.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw=
|
||||
github.com/wundergraph/graphql-go-tools/v2 v2.20.3 h1:LfVi9VxZ3osk9j0+TQy8ILlKOtcOpssKnmupBfeT2F8=
|
||||
github.com/wundergraph/graphql-go-tools/v2 v2.20.3/go.mod h1:w/eZQt3znffRePA0raMhTjhKSgbt0Fywf26/p/B1uOQ=
|
||||
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1 h1:X6269JoAzHIKCVmtgMHZH3m7xOpACSp37ca3eODe9iU=
|
||||
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1/go.mod h1:EAs0d6Eh0aDiQkUJlSWErHqgHFQdxx0e8I7aG/2FarY=
|
||||
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.23.0 h1:qcteJH9D7kHaOgLQ0fzlW9dv42hSa0Vluqt7p4kooWA=
|
||||
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.23.0/go.mod h1:LrA7I7etRmhIC1PjO8c26BHm+gWsy2rC3eSMe5+XUWE=
|
||||
gitlab.com/unboundsoftware/eventsourced/pg/v2 v2.0.2 h1:6pWgKGnxBq7bVFbeo6wPWBNW5OXU7acgexywC3N9dCM=
|
||||
gitlab.com/unboundsoftware/eventsourced/pg/v2 v2.0.2/go.mod h1:S0oBU9kHxuAn5G/3DxvlMbf5BSfPPjhiXuwU+yVrTBg=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/bridges/otelslog v0.20.1 h1:5sHc4ToTFjfSZCtGAAM6jPunICAmJX73htv372T4ipc=
|
||||
@@ -237,6 +261,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
|
||||
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/cache"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/graph/model"
|
||||
|
||||
@@ -3,7 +3,7 @@ package graph
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/graph/model"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
"gitea.unbound.se/unboundsoftware/schemas/graph/generated"
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"codeberg.org/eventsourced/eventsourced"
|
||||
"github.com/auth0/go-jwt-middleware/v3/core"
|
||||
"github.com/auth0/go-jwt-middleware/v3/validator"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
|
||||
|
||||
"gitea.unbound.se/unboundsoftware/schemas/domain"
|
||||
)
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@
|
||||
{
|
||||
"groupName": "Eventsourced",
|
||||
"matchPackageNames": [
|
||||
"gitlab.com/unboundsoftware/eventsourced/**"
|
||||
"codeberg.org/eventsourced/**",
|
||||
"codeberg.org/messaging/**"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user