Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/go_modules/github.com/foomo/gotsr…
Browse files Browse the repository at this point in the history
…pc/v2-2.7.3
  • Loading branch information
dreadl0ck authored Aug 12, 2024
2 parents b088581 + 54d44aa commit 6ea2fd9
Show file tree
Hide file tree
Showing 33 changed files with 1,297 additions and 631 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0

- run: git fetch --force --tags

- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
check-latest: true
go-version-file: 'go.mod'

- uses: goreleaser/goreleaser-action@v4
- uses: goreleaser/goreleaser-action@v5
with:
version: latest
args: release --clean
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
check-latest: true
go-version-file: 'go.mod'
Expand Down
26 changes: 17 additions & 9 deletions domain/redirectdefinition/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,55 @@ import (
redirectquery "github.com/foomo/redirects/domain/redirectdefinition/query"
redirectrepository "github.com/foomo/redirects/domain/redirectdefinition/repository"
redirectstore "github.com/foomo/redirects/domain/redirectdefinition/store"
redirectnats "github.com/foomo/redirects/pkg/nats"
redirectprovider "github.com/foomo/redirects/pkg/provider"
"go.uber.org/zap"
)

// API for the domain
type (
API struct {
qry Queries
cmd Commands
repo redirectrepository.BaseRedirectsDefinitionRepository
l *zap.Logger
//meter *cmrccommonmetric.Meter
l *zap.Logger
qry Queries
cmd Commands
getSiteIdentifierProvider redirectprovider.SiteIdentifierProviderFunc
repo redirectrepository.RedirectsDefinitionRepository
}
Option func(api *API)
)

func NewAPI(
l *zap.Logger,
repo redirectrepository.BaseRedirectsDefinitionRepository,
repo redirectrepository.RedirectsDefinitionRepository,
updateSignal *redirectnats.UpdateSignal,
opts ...Option,
) (*API, error) {

inst := &API{
l: l,
repo: repo,
//meter: cmrccommonmetric.NewMeter(l, "checkout", telemetry.Meter()),
}
if inst.l == nil {
return nil, errors.New("missing logger")
}
inst.cmd = Commands{
CreateRedirects: redirectcommand.CreateRedirectsHandlerComposed(
redirectcommand.CreateRedirectsHandler(inst.repo),
redirectcommand.CreateRedirectsConsolidateMiddleware(repo, false),
redirectcommand.CreateRedirectsAutoCreateMiddleware(),
redirectcommand.CreateRedirectsPublishMiddleware(updateSignal),
),
CreateRedirect: redirectcommand.CreateRedirectHandlerComposed(
redirectcommand.CreateRedirectHandler(inst.repo),
redirectcommand.CreateRedirectPublishMiddleware(updateSignal),
),
UpdateRedirect: redirectcommand.UpdateRedirectHandlerComposed(
redirectcommand.UpdateRedirectHandler(inst.repo),
redirectcommand.UpdateRedirectPublishMiddleware(updateSignal),
),
DeleteRedirect: redirectcommand.DeleteRedirectHandlerComposed(
redirectcommand.DeleteRedirectHandler(inst.repo),
redirectcommand.DeleteRedirectPublishMiddleware(updateSignal),
),
}
inst.qry = Queries{
Expand Down Expand Up @@ -88,10 +96,10 @@ func (a *API) DeleteRedirect(ctx context.Context, cmd redirectcommand.DeleteRedi
return a.cmd.DeleteRedirect(ctx, a.l, cmd)
}

func (a *API) GetRedirects(ctx context.Context) (redirects *redirectstore.RedirectDefinitions, err error) {
func (a *API) GetRedirects(ctx context.Context) (map[redirectstore.Dimension]map[redirectstore.RedirectSource]*redirectstore.RedirectDefinition, error) {
return a.qry.GetRedirects(ctx, a.l)
}

func (a *API) Search(ctx context.Context, qry redirectquery.Search) (redirect *redirectstore.RedirectDefinitions, err error) {
func (a *API) Search(ctx context.Context, qry redirectquery.Search) (map[redirectstore.RedirectSource]*redirectstore.RedirectDefinition, error) {
return a.qry.Search(ctx, a.l, qry)
}
20 changes: 19 additions & 1 deletion domain/redirectdefinition/command/createredirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

redirectrepository "github.com/foomo/redirects/domain/redirectdefinition/repository"
redirectstore "github.com/foomo/redirects/domain/redirectdefinition/store"
redirectnats "github.com/foomo/redirects/pkg/nats"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)
Expand All @@ -24,7 +25,7 @@ type (
)

// CreateRedirectHandler ...
func CreateRedirectHandler(repo redirectrepository.BaseRedirectsDefinitionRepository) CreateRedirectHandlerFn {
func CreateRedirectHandler(repo redirectrepository.RedirectsDefinitionRepository) CreateRedirectHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirect) error {
return repo.Insert(ctx, cmd.RedirectDefinition)
}
Expand All @@ -49,3 +50,20 @@ func CreateRedirectHandlerComposed(handler CreateRedirectHandlerFn, middlewares
return handler(ctx, l, cmd)
})
}

// CreateRedirectPublishMiddleware ...
func CreateRedirectPublishMiddleware(updateSignal *redirectnats.UpdateSignal) CreateRedirectMiddlewareFn {
return func(next CreateRedirectHandlerFn) CreateRedirectHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirect) error {
err := next(ctx, l, cmd)
if err != nil {
return err
}
err = updateSignal.Publish()
if err != nil {
return err
}
return nil
}
}
}
156 changes: 130 additions & 26 deletions domain/redirectdefinition/command/createredirectsfromcontentserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ import (
"strings"

"github.com/foomo/contentserver/content"
keellog "github.com/foomo/keel/log"
redirectrepository "github.com/foomo/redirects/domain/redirectdefinition/repository"
redirectstore "github.com/foomo/redirects/domain/redirectdefinition/store"
redirectdefinitionutils "github.com/foomo/redirects/domain/redirectdefinition/utils"
redirectnats "github.com/foomo/redirects/pkg/nats"

"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)

const dimension = "de"

type (
// CreateRedirects command
CreateRedirects struct {
OldState map[string]*content.RepoNode `json:"oldState"`
NewState map[string]*content.RepoNode `json:"newState"`
OldState map[string]*content.RepoNode `json:"oldState"`
NewState map[string]*content.RepoNode `json:"newState"`
RedirectsToUpsert []*redirectstore.RedirectDefinition `json:"redirectsToUpsert,omitempty"`
RedirectsToDelete []redirectstore.EntityID `json:"redirectsToDeletee,omitempty"`
}
// CreateRedirectsHandlerFn handler
CreateRedirectsHandlerFn func(ctx context.Context, l *zap.Logger, cmd CreateRedirects) error
Expand All @@ -29,37 +32,22 @@ type (
)

// CreateRedirectsHandler ...
func CreateRedirectsHandler(repo redirectrepository.BaseRedirectsDefinitionRepository) CreateRedirectsHandlerFn {
func CreateRedirectsHandler(repo redirectrepository.RedirectsDefinitionRepository) CreateRedirectsHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirects) error {
l.Info("calling create automatic redirects")
newDefinitions, err := redirectdefinitionutils.AutoCreateRedirectDefinitions(l, cmd.OldState[dimension], cmd.NewState[dimension])
if err != nil {
l.Error("failed to execute auto create redirects", zap.Error(err))
return err
}
oldDefinitions, err := repo.FindAll(ctx)
if err != nil {
l.Error("failed to fetch existing definitions", zap.Error(err))
return err
}
l.Info("calling consolidate automatic redirects")
consolidatedDefs, deletedDefs := redirectdefinitionutils.ConsolidateRedirectDefinitions(l, *oldDefinitions, newDefinitions)

if len(consolidatedDefs) > 0 {
updateErr := repo.UpsertMany(ctx, &consolidatedDefs)
if len(cmd.RedirectsToUpsert) > 0 {
updateErr := repo.UpsertMany(ctx, cmd.RedirectsToUpsert)
if updateErr != nil {
l.Error("failed to updated definitions", zap.Error(updateErr))
keellog.WithError(l, updateErr).Error("failed to updated definitions")
return updateErr
}
}
if len(deletedDefs) > 0 {
deleteErr := repo.DeleteMany(ctx, deletedDefs)
if len(cmd.RedirectsToDelete) > 0 {
deleteErr := repo.DeleteMany(ctx, cmd.RedirectsToDelete)
if deleteErr != nil {
l.Error("failed to delete definitions", zap.Error(deleteErr))
keellog.WithError(l, deleteErr).Error("failed to delete definitions")
return deleteErr
}
}

l.Info("successfully finished create automatic redirects")
return nil
}
Expand All @@ -84,3 +72,119 @@ func CreateRedirectsHandlerComposed(handler CreateRedirectsHandlerFn, middleware
return handler(ctx, l, cmd)
})
}

// CreateRedirectsPublishMiddleware ...
func CreateRedirectsPublishMiddleware(updateSignal *redirectnats.UpdateSignal) CreateRedirectsMiddlewareFn {
return func(next CreateRedirectsHandlerFn) CreateRedirectsHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirects) error {
err := next(ctx, l, cmd)
if err != nil {
return err
}
l.Info("publishing update signal")
err = updateSignal.Publish()
if err != nil {
return err
}
return nil
}
}
}

// CreateRedirectsAutoCreateMiddleware ...
func CreateRedirectsAutoCreateMiddleware() CreateRedirectsMiddlewareFn {
return func(next CreateRedirectsHandlerFn) CreateRedirectsHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirects) error {
l.Info("auto creating redirects")
dimensions := map[string]struct{}{}
for dim := range cmd.OldState {
dimensions[dim] = struct{}{}
}

for dim := range cmd.NewState {
dimensions[dim] = struct{}{}
}

for dimension := range dimensions {
oldNodeMap := redirectdefinitionutils.CreateFlatRepoNodeMap(cmd.OldState[dimension], make(map[string]*content.RepoNode))
newNodeMap := redirectdefinitionutils.CreateFlatRepoNodeMap(cmd.NewState[dimension], make(map[string]*content.RepoNode))

newDefinitions, err := redirectdefinitionutils.AutoCreateRedirectDefinitions(
l,
oldNodeMap,
newNodeMap,
redirectstore.Dimension(dimension),
)
if err != nil {
keellog.WithError(l, err).Error("failed to execute auto create redirects")
return err
}
cmd.RedirectsToUpsert = append(cmd.RedirectsToUpsert, newDefinitions...)
}
return next(ctx, l, cmd)
}
}
}

// CreateRedirectsConsolidateMiddleware ...
func CreateRedirectsConsolidateMiddleware(repo redirectrepository.RedirectsDefinitionRepository, autoDelete bool) CreateRedirectsMiddlewareFn {
return func(next CreateRedirectsHandlerFn) CreateRedirectsHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd CreateRedirects) error {
l.Info("consolidating redirect definitions")
redirectsToUpsert := []*redirectstore.RedirectDefinition{}
redirectsToDelete := []redirectstore.EntityID{}

// get all current definitions for the dimension from the database
allCurrentDefinitions, err := repo.FindAll(ctx, true)
if err != nil {
l.Error("failed to fetch existing definitions", zap.Error(err))
return err
}
for dimension, currentDefinitions := range allCurrentDefinitions {
defs, ids := redirectdefinitionutils.ConsolidateRedirectDefinitions(
l,
cmd.RedirectsToUpsert,
currentDefinitions,
redirectdefinitionutils.CreateFlatRepoNodeMap(cmd.NewState[string(dimension)], make(map[string]*content.RepoNode)),
)
redirectsToUpsert = append(redirectsToUpsert, defs...)

// if we are in auto delete mode we add the ids to the delete list
// otherwise we soft delete the definitions
if autoDelete {
redirectsToDelete = append(redirectsToDelete, ids...)
} else {
softDeleteStrategy(ids, defs, currentDefinitions)
}
}
cmd.RedirectsToUpsert = redirectsToUpsert
cmd.RedirectsToDelete = redirectsToDelete

return next(ctx, l, cmd)
}
}
}

// softDeleteStrategy ...
func softDeleteStrategy(
idsToDelete []redirectstore.EntityID,
newRedirects []*redirectstore.RedirectDefinition,
currentDefinitions map[redirectstore.RedirectSource]*redirectstore.RedirectDefinition,
) (redirectsToUpsert []*redirectstore.RedirectDefinition) {
additionalRedirects := []*redirectstore.RedirectDefinition{}
for _, id := range idsToDelete {
for _, def := range newRedirects {
if def.ID == id {
def.Stale = true
continue
}
}
for _, def := range currentDefinitions {
if def.ID == id {
def.Stale = true
additionalRedirects = append(additionalRedirects, def)
}
}
}
return append(newRedirects, additionalRedirects...)
}
24 changes: 21 additions & 3 deletions domain/redirectdefinition/command/deleteredirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import (

redirectrepository "github.com/foomo/redirects/domain/redirectdefinition/repository"
redirectstore "github.com/foomo/redirects/domain/redirectdefinition/store"
redirectnats "github.com/foomo/redirects/pkg/nats"
"go.opentelemetry.io/otel/trace"
"go.uber.org/zap"
)

type (
// DeleteRedirect command
DeleteRedirect struct {
Source redirectstore.RedirectSource `json:"source"`
ID redirectstore.EntityID `json:"id"`
}
// DeleteRedirectHandlerFn handler
DeleteRedirectHandlerFn func(ctx context.Context, l *zap.Logger, cmd DeleteRedirect) error
Expand All @@ -24,9 +25,9 @@ type (
)

// DeleteRedirectHandler ...
func DeleteRedirectHandler(repo redirectrepository.BaseRedirectsDefinitionRepository) DeleteRedirectHandlerFn {
func DeleteRedirectHandler(repo redirectrepository.RedirectsDefinitionRepository) DeleteRedirectHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd DeleteRedirect) error {
return repo.Delete(ctx, string(cmd.Source))
return repo.Delete(ctx, cmd.ID)
}
}

Expand All @@ -49,3 +50,20 @@ func DeleteRedirectHandlerComposed(handler DeleteRedirectHandlerFn, middlewares
return handler(ctx, l, cmd)
})
}

// DeleteRedirectPublishMiddleware ...
func DeleteRedirectPublishMiddleware(updateSignal *redirectnats.UpdateSignal) DeleteRedirectMiddlewareFn {
return func(next DeleteRedirectHandlerFn) DeleteRedirectHandlerFn {
return func(ctx context.Context, l *zap.Logger, cmd DeleteRedirect) error {
err := next(ctx, l, cmd)
if err != nil {
return err
}
err = updateSignal.Publish()
if err != nil {
return err
}
return nil
}
}
}
Loading

0 comments on commit 6ea2fd9

Please sign in to comment.