Skip to content
Draft
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
21 changes: 9 additions & 12 deletions internal/alias/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,30 @@ import (
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/util"
)

// A Repository stores and retrieves the persistent types in the alias
// package. It is not safe to use a repository concurrently.
type Repository struct {
reader db.Reader
writer db.Writer
kms *kms.Kms
txm db.TransactionManager
kms *kms.Kms
}

// NewRepository creates a new Repository. The returned repository should
// only be used for one transaction and it is not safe for concurrent go
// routines to access it.
func NewRepository(ctx context.Context, r db.Reader, w db.Writer, kms *kms.Kms) (*Repository, error) {
func NewRepository(ctx context.Context, txm db.TransactionManager, kms *kms.Kms) (*Repository, error) {
const op = "alias.NewRepository"
switch {
case r == nil:
return nil, errors.New(ctx, errors.InvalidParameter, op, "db.Reader")
case w == nil:
return nil, errors.New(ctx, errors.InvalidParameter, op, "db.Writer")
case util.IsNil(txm):
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing transaction manager")
case kms == nil:
return nil, errors.New(ctx, errors.InvalidParameter, op, "kms")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing kms")
}

return &Repository{
reader: r,
writer: w,
kms: kms,
txm: txm,
kms: kms,
}, nil
}
11 changes: 7 additions & 4 deletions internal/alias/repository_alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"

"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
)

Expand All @@ -18,11 +19,13 @@ func (r *Repository) lookupAliasByValue(ctx context.Context, value string) (*Ali
return nil, errors.New(ctx, errors.InvalidParameter, op, "value is empty")
}
a := allocAlias()
if err := r.reader.LookupWhere(ctx, a, "value = $1", []any{value}); err != nil {
if errors.IsNotFoundError(err) {
return nil, nil
if _, err := r.txm.DoRoTx(ctx, func(reader db.Reader) error {
if err := reader.LookupWhere(ctx, a, "value = $1", []any{value}); err != nil && !errors.IsNotFoundError(err) {
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %q", value)))
}
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %q", value)))
return nil
}); err != nil {
return nil, err
}
return a, nil
}
13 changes: 13 additions & 0 deletions internal/alias/target/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,16 @@ func TestAlias(t *testing.T, rw *db.Db, alias string, opt ...Option) *Alias {
require.NoError(t, rw.Create(ctx, a, db.WithDebug(true)))
return a
}

// TODO: Replace TestAlias with this when migrating to the TransactionManager
func TestNewAlias(t *testing.T, txm db.TransactionManager, alias string, opt ...Option) *Alias {
t.Helper()
ctx := context.Background()

a, err := NewAlias(ctx, "global", alias, opt...)
require.NoError(t, err)
a.PublicId, err = newAliasId(ctx)
require.NoError(t, err)
require.NoError(t, txm.Writer().Create(ctx, a, db.WithDebug(true)))
return a
}
3 changes: 2 additions & 1 deletion internal/daemon/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ func New(ctx context.Context, conf *Config) (*Controller, error) {

// Set up repo stuff
dbase := db.New(c.conf.Database)
txManager := db.NewTransactionManager(c.conf.Database)
c.kms, err = kms.New(ctx, dbase, dbase)
if err != nil {
return nil, fmt.Errorf("error creating kms cache: %w", err)
Expand Down Expand Up @@ -478,7 +479,7 @@ func New(ctx context.Context, conf *Config) (*Controller, error) {
return billing.NewRepository(ctx, dbase)
}
c.AliasRepoFn = func() (*alias.Repository, error) {
return alias.NewRepository(ctx, dbase, dbase, c.kms)
return alias.NewRepository(ctx, txManager, c.kms)
}
c.TargetAliasRepoFn = func() (*talias.Repository, error) {
return talias.NewRepository(ctx, dbase, dbase, c.kms)
Expand Down
8 changes: 4 additions & 4 deletions internal/daemon/controller/interceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,18 +667,18 @@ func (m *streamMock) RecvToClient() (*httpbody.HttpBody, error) {
func Test_aliasResolutionInterceptor(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
txm := db.NewTransactionManager(conn)
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)

aliasRepoFn := func() (*alias.Repository, error) {
return alias.NewRepository(context.Background(), rw, rw, kmsCache)
return alias.NewRepository(context.Background(), txm, kmsCache)
}

_, proj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
tar := tcp.TestTarget(ctx, t, conn, proj.GetPublicId(), "test-target")
al := talias.TestAlias(t, rw, "test-alias.example", talias.WithDestinationId(tar.GetPublicId()))
alWithoutDest := talias.TestAlias(t, rw, "no-destination.alias")
al := talias.TestNewAlias(t, txm, "test-alias.example", talias.WithDestinationId(tar.GetPublicId()))
alWithoutDest := talias.TestNewAlias(t, txm, "no-destination.alias")

interceptor := aliasResolutionInterceptor(ctx, aliasRepoFn)
require.NotNil(t, interceptor)
Expand Down
1 change: 0 additions & 1 deletion internal/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/hashicorp/boundary/internal/event"
"github.com/hashicorp/go-dbw"
_ "github.com/jackc/pgx/v5"

"gorm.io/driver/postgres"
)

Expand Down
9 changes: 5 additions & 4 deletions internal/db/read_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ const (
DescendingOrderBy
)

// Reader interface defines lookups/searching for resources
// TxHandler defines a handler for a func that writes a transaction for use with DoTx
type TxHandler func(Reader, Writer) error

// Reader interface defines lookups/searching for resources. It does
// not allow for writing to the db.
type Reader interface {
// LookupById will lookup a resource by its primary key id, which must be
// unique. If the resource implements either ResourcePublicIder or
Expand Down Expand Up @@ -170,9 +174,6 @@ type RetryInfo struct {
Backoff time.Duration
}

// TxHandler defines a handler for a func that writes a transaction for use with DoTx
type TxHandler func(Reader, Writer) error

// ResourcePublicIder defines an interface that LookupByPublicId() can use to
// get the resource's public id.
type ResourcePublicIder interface {
Expand Down
Loading