fix: instance remove (#4602)

This commit is contained in:
Livio Spring
2022-10-26 15:06:48 +02:00
committed by GitHub
parent 001636f2b4
commit d721f725fd
89 changed files with 656 additions and 122 deletions

View File

@@ -12,7 +12,7 @@ import (
"github.com/zitadel/zitadel/internal/eventstore/repository"
)
//Eventstore abstracts all functions needed to store valid events
// Eventstore abstracts all functions needed to store valid events
// and filters the stored events
type Eventstore struct {
repo repository.Repository
@@ -32,13 +32,13 @@ func NewEventstore(repo repository.Repository) *Eventstore {
}
}
//Health checks if the eventstore can properly work
// Health checks if the eventstore can properly work
// It checks if the repository can serve load
func (es *Eventstore) Health(ctx context.Context) error {
return es.repo.Health(ctx)
}
//Push pushes the events in a single transaction
// Push pushes the events in a single transaction
// an event needs at least an aggregate
func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) {
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds)
@@ -119,7 +119,7 @@ func uniqueConstraintsToRepository(instanceID string, constraints []*EventUnique
return uniqueConstraints
}
//Filter filters the stored events based on the searchQuery
// Filter filters the stored events based on the searchQuery
// and maps the events to the defined event structs
func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
@@ -165,7 +165,7 @@ type reducer interface {
AppendEvents(...Event)
}
//FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function
// FilterToReducer filters the events based on the search query, appends all events to the reducer and calls it's reduce function
func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQueryBuilder, r reducer) error {
events, err := es.Filter(ctx, searchQuery)
if err != nil {
@@ -177,7 +177,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu
return r.Reduce()
}
//LatestSequence filters the latest sequence for the given search query
// LatestSequence filters the latest sequence for the given search query
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil {
@@ -186,7 +186,7 @@ func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQu
return es.repo.LatestSequence(ctx, query)
}
//InstanceIDs returns the instance ids found by the search query
// InstanceIDs returns the instance ids found by the search query
func (es *Eventstore) InstanceIDs(ctx context.Context, queryFactory *SearchQueryBuilder) ([]string, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil {
@@ -201,7 +201,7 @@ type QueryReducer interface {
Query() *SearchQueryBuilder
}
//FilterToQueryReducer filters the events based on the search query of the query function,
// FilterToQueryReducer filters the events based on the search query of the query function,
// appends all events to the reducer and calls it's reduce function
func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer) error {
events, err := es.Filter(ctx, r.Query())
@@ -213,7 +213,7 @@ func (es *Eventstore) FilterToQueryReducer(ctx context.Context, r QueryReducer)
return r.Reduce()
}
//RegisterFilterEventMapper registers a function for mapping an eventstore event to an event
// RegisterFilterEventMapper registers a function for mapping an eventstore event to an event
func (es *Eventstore) RegisterFilterEventMapper(eventType EventType, mapper func(*repository.Event) (Event, error)) *Eventstore {
if mapper == nil || eventType == "" {
return es
@@ -258,6 +258,8 @@ func uniqueConstraintActionToRepository(action UniqueConstraintAction) repositor
return repository.UniqueConstraintAdd
case UniqueConstraintRemove:
return repository.UniqueConstraintRemoved
case UniqueConstraintInstanceRemove:
return repository.UniqueConstraintInstanceRemoved
default:
return repository.UniqueConstraintAdd
}

View File

@@ -92,6 +92,8 @@ const (
uniqueDelete = `DELETE FROM eventstore.unique_constraints
WHERE unique_type = $1 and unique_field = $2 and instance_id = $3`
uniqueDeleteInstance = `DELETE FROM eventstore.unique_constraints
WHERE instance_id = $1`
)
type CRDB struct {
@@ -193,7 +195,7 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
return caos_errs.ThrowAlreadyExists(err, "SQL-M0dsf", uniqueConstraint.ErrorMessage)
}
return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint ")
return caos_errs.ThrowInternal(err, "SQL-dM9ds", "unable to create unique constraint")
}
case repository.UniqueConstraintRemoved:
_, err := tx.ExecContext(ctx, uniqueDelete, uniqueConstraint.UniqueType, uniqueConstraint.UniqueField, uniqueConstraint.InstanceID)
@@ -201,7 +203,14 @@ func (db *CRDB) handleUniqueConstraints(ctx context.Context, tx *sql.Tx, uniqueC
logging.WithFields(
"unique_type", uniqueConstraint.UniqueType,
"unique_field", uniqueConstraint.UniqueField).WithError(err).Info("delete unique constraint failed")
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint ")
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraint")
}
case repository.UniqueConstraintInstanceRemoved:
_, err := tx.ExecContext(ctx, uniqueDeleteInstance, uniqueConstraint.InstanceID)
if err != nil {
logging.WithFields(
"instance_id", uniqueConstraint.InstanceID).WithError(err).Info("delete instance unique constraints failed")
return caos_errs.ThrowInternal(err, "SQL-6n88i", "unable to remove unique constraints of instance")
}
}
}

View File

@@ -379,24 +379,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
}},
},
{
name: "push 1 event and add asset",
name: "push 1 event and remove instance unique constraints",
args: args{
ctx: context.Background(),
events: []*repository.Event{
generateEvent(t, "12"),
},
uniqueConstraints: generateRemoveInstanceUniqueConstraints(t, "instanceID"),
uniqueDataType: "usernames",
uniqueDataField: "testremove",
uniqueDataInstanceID: "instanceID",
},
res: res{
wantErr: false,
eventsRes: eventsRes{
pushedEventsCount: 1,
assetCount: 1,
uniqueCount: 0,
aggID: []string{"12"},
aggType: repository.AggregateType(t.Name()),
}},
},
{
name: "push 1 event and remove asset",
name: "push 1 event and add asset",
args: args{
ctx: context.Background(),
events: []*repository.Event{
@@ -407,11 +411,28 @@ func TestCRDB_Push_OneAggregate(t *testing.T) {
wantErr: false,
eventsRes: eventsRes{
pushedEventsCount: 1,
assetCount: 0,
assetCount: 1,
aggID: []string{"13"},
aggType: repository.AggregateType(t.Name()),
}},
},
{
name: "push 1 event and remove asset",
args: args{
ctx: context.Background(),
events: []*repository.Event{
generateEvent(t, "14"),
},
},
res: res{
wantErr: false,
eventsRes: eventsRes{
pushedEventsCount: 1,
assetCount: 0,
aggID: []string{"14"},
aggType: repository.AggregateType(t.Name()),
}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -1201,3 +1222,13 @@ func generateRemoveUniqueConstraint(t *testing.T, table, uniqueField string) *re
return e
}
func generateRemoveInstanceUniqueConstraints(t *testing.T, instanceID string) *repository.UniqueConstraint {
t.Helper()
e := &repository.UniqueConstraint{
InstanceID: instanceID,
Action: repository.UniqueConstraintInstanceRemoved,
}
return e
}

View File

@@ -1,6 +1,6 @@
package repository
//UniqueCheck represents all information about a unique attribute
// UniqueCheck represents all information about a unique attribute
type UniqueConstraint struct {
//UniqueField is the field which should be unique
UniqueField string
@@ -23,6 +23,7 @@ type UniqueConstraintAction int32
const (
UniqueConstraintAdd UniqueConstraintAction = iota
UniqueConstraintRemoved
UniqueConstraintInstanceRemoved
uniqueConstraintActionCount
)

View File

@@ -18,6 +18,7 @@ type UniqueConstraintAction int32
const (
UniqueConstraintAdd UniqueConstraintAction = iota
UniqueConstraintRemove
UniqueConstraintInstanceRemove
)
func NewAddEventUniqueConstraint(
@@ -42,6 +43,12 @@ func NewRemoveEventUniqueConstraint(
}
}
func NewRemoveInstanceUniqueConstraints() *EventUniqueConstraint {
return &EventUniqueConstraint{
Action: UniqueConstraintInstanceRemove,
}
}
func NewAddGlobalEventUniqueConstraint(
uniqueType,
uniqueField,