Skip to content

Commit

Permalink
fix(upgrades): upgrades when creating a new ledger on an already migr…
Browse files Browse the repository at this point in the history
…ation bucket
  • Loading branch information
gfyrag committed Dec 5, 2024
1 parent b69289b commit 079c13e
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 107 deletions.
196 changes: 98 additions & 98 deletions internal/README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions internal/api/v2/controllers_ledgers_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func createLedger(systemController system.Controller) http.HandlerFunc {
switch {
case errors.Is(err, system.ErrInvalidLedgerConfiguration{}) ||
errors.Is(err, ledger.ErrInvalidLedgerName{}) ||
errors.Is(err, system.ErrBucketUpgrading) ||
errors.Is(err, ledger.ErrInvalidBucketName{}):
api.BadRequest(w, common.ErrValidation, err)
case errors.Is(err, system.ErrLedgerAlreadyExists):
Expand Down
7 changes: 7 additions & 0 deletions internal/api/v2/controllers_ledgers_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ func TestLedgersCreate(t *testing.T) {
expectStatusCode: http.StatusBadRequest,
expectErrorCode: common.ErrValidation,
},
{
name: "bucket actually upgrading",
expectedBackendCall: true,
returnErr: system.ErrBucketUpgrading,
expectStatusCode: http.StatusBadRequest,
expectErrorCode: common.ErrValidation,
},
{
name: "unexpected error",
expectedBackendCall: true,
Expand Down
1 change: 1 addition & 0 deletions internal/controller/system/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

var (
ErrLedgerAlreadyExists = errors.New("ledger already exists")
ErrBucketUpgrading = errors.New("bucket is upgrading")
ErrExperimentalFeaturesDisabled = errors.New("experimental features are disabled")
)

Expand Down
1 change: 1 addition & 0 deletions internal/storage/bucket/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Bucket interface {
HasMinimalVersion(ctx context.Context) (bool, error)
IsUpToDate(ctx context.Context) (bool, error)
GetMigrationsInfo(ctx context.Context) ([]migrations.Info, error)
IsInitialized(context.Context) (bool, error)
}

type Factory interface {
Expand Down
12 changes: 12 additions & 0 deletions internal/storage/bucket/default_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"context"
_ "embed"
"errors"
"fmt"
"github.com/formancehq/go-libs/v2/migrations"
ledger "github.com/formancehq/ledger/internal"
Expand All @@ -22,6 +23,17 @@ type DefaultBucket struct {
tracer trace.Tracer
}

func (b *DefaultBucket) IsInitialized(ctx context.Context) (bool, error) {
_, err := GetMigrator(b.db, b.name).GetLastVersion(ctx)
if err == nil {
return true, nil
}
if errors.Is(err, migrations.ErrMissingVersionTable) {
return false, nil
}
return false, err
}

func (b *DefaultBucket) IsUpToDate(ctx context.Context) (bool, error) {
return GetMigrator(b.db, b.name).IsUpToDate(ctx)
}
Expand Down
15 changes: 15 additions & 0 deletions internal/storage/driver/buckets_generated_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions internal/storage/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ func (d *Driver) CreateLedger(ctx context.Context, l *ledger.Ledger) (*ledgersto
}

b := d.bucketFactory.Create(l.Bucket)
isInitialized, err := b.IsInitialized(ctx)
if err != nil {
return nil, fmt.Errorf("checking if bucket is initialized: %w", err)
}
if isInitialized {
upToDate, err := b.IsUpToDate(ctx)
if err != nil {
return nil, fmt.Errorf("checking if bucket is up to date: %w", err)
}

if !upToDate {
return nil, systemcontroller.ErrBucketUpgrading
}
}

if err := b.Migrate(
ctx,
make(chan struct{}),
Expand Down
4 changes: 4 additions & 0 deletions internal/storage/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ func TestLedgersCreate(t *testing.T) {
systemStore.EXPECT().
CreateLedger(gomock.Any(), l)

bucket.EXPECT().
IsInitialized(gomock.Any()).
Return(false, nil)

bucket.EXPECT().
Migrate(gomock.Any(), gomock.Any(), gomock.Any()).
Return(nil)
Expand Down
26 changes: 17 additions & 9 deletions tools/generator/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,19 +147,27 @@ func run(cmd *cobra.Command, args []string) error {
)

logging.FromContext(cmd.Context()).Infof("Creating ledger '%s' if not exists", targetedLedger)
_, err = client.Ledger.V2.CreateLedger(cmd.Context(), operations.V2CreateLedgerRequest{
_, err = client.Ledger.V2.GetLedger(cmd.Context(), operations.V2GetLedgerRequest{
Ledger: targetedLedger,
V2CreateLedgerRequest: &components.V2CreateLedgerRequest{
Bucket: &ledgerBucket,
Metadata: ledgerMetadata,
Features: ledgerFeatures,
},
})
if err != nil {
sdkError := &sdkerrors.V2ErrorResponse{}
if !errors.As(err, &sdkError) || (sdkError.ErrorCode != components.V2ErrorsEnumLedgerAlreadyExists &&
sdkError.ErrorCode != components.V2ErrorsEnumValidation) {
return fmt.Errorf("failed to create ledger: %w", err)
if !errors.As(err, &sdkError) || sdkError.ErrorCode != components.V2ErrorsEnumNotFound {
return fmt.Errorf("failed to get ledger: %w", err)
}
_, err = client.Ledger.V2.CreateLedger(cmd.Context(), operations.V2CreateLedgerRequest{
Ledger: targetedLedger,
V2CreateLedgerRequest: &components.V2CreateLedgerRequest{
Bucket: &ledgerBucket,
Metadata: ledgerMetadata,
Features: ledgerFeatures,
},
})
if err != nil {
if !errors.As(err, &sdkError) || (sdkError.ErrorCode != components.V2ErrorsEnumLedgerAlreadyExists &&
sdkError.ErrorCode != components.V2ErrorsEnumValidation) {
return fmt.Errorf("failed to create ledger: %w", err)
}
}
}

Expand Down

0 comments on commit 079c13e

Please sign in to comment.