Skip to content

Commit

Permalink
Audit info store DB implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandros Filios <[email protected]>
  • Loading branch information
alexandrosfilios committed Jan 20, 2025
1 parent 3e6f757 commit 8ed155a
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 3 deletions.
21 changes: 20 additions & 1 deletion platform/view/sdk/dig/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
driver4 "github.com/hyperledger-labs/fabric-smart-client/platform/common/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/common/utils"
"github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/collections"
"github.com/hyperledger-labs/fabric-smart-client/platform/fabric/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/driver"
driver2 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/badger"
mem "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/memory"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kms"
driver3 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kms/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/auditinfo"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/binding"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/signerinfo"
"github.com/pkg/errors"
Expand Down Expand Up @@ -75,6 +76,24 @@ func newSignerInfoStore(in struct {
return nil, errors.New("driver not found")
}

func newAuditInfoStore(in struct {
dig.In
KVS *kvs.KVS
Config driver.ConfigService
Drivers []driver2.NamedDriver `group:"db-drivers"`
}) (driver4.AuditInfoStore, error) {
driverName := driver4.PersistenceType(utils.DefaultString(in.Config.GetString("fsc.auditinfo.persistence.type"), string(mem.MemoryPersistence)))
if unsupportedStores.Contains(driverName) {
return auditinfo.NewKVSBased(in.KVS), nil
}
for _, d := range in.Drivers {
if d.Name == driverName {
return auditinfo.NewWithConfig(d.Driver, "_default", in.Config)
}
}
return nil, errors.New("driver not found")
}

func newKMSDriver(in struct {
dig.In
Config driver.ConfigService
Expand Down
3 changes: 1 addition & 2 deletions platform/view/sdk/dig/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/metrics/operations"
view3 "github.com/hyperledger-labs/fabric-smart-client/platform/view/services/server/view"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/server/view/protos"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/storage/auditinfo"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/tracing"
"go.opentelemetry.io/otel/trace"
"go.uber.org/dig"
Expand Down Expand Up @@ -102,7 +101,7 @@ func (p *SDK) Install() error {
p.C.Provide(view.NewSigService, dig.As(new(view3.VerifierProvider), new(view3.SignerProvider))),
p.C.Provide(newBindingStore, dig.As(new(driver4.BindingStore))),
p.C.Provide(newSignerInfoStore, dig.As(new(driver4.SignerInfoStore))),
p.C.Provide(auditinfo.NewKVSBased, dig.As(new(driver4.AuditInfoStore))),
p.C.Provide(newAuditInfoStore, dig.As(new(driver4.AuditInfoStore))),
p.C.Provide(endpoint.NewService),
p.C.Provide(digutils.Identity[*endpoint.Service](), dig.As(new(driver.EndpointService))),
p.C.Provide(view.NewEndpointService),
Expand Down
4 changes: 4 additions & 0 deletions platform/view/services/db/driver/badger/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,7 @@ func (d *Driver) NewBinding(string, driver.Config) (driver.BindingPersistence, e
func (d *Driver) NewSignerInfo(string, driver.Config) (driver.SignerInfoPersistence, error) {
panic("not implemented")
}

func (d *Driver) NewAuditInfo(string, driver.Config) (driver.AuditInfoPersistence, error) {
panic("not implemented")
}
4 changes: 4 additions & 0 deletions platform/view/services/db/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type BindingPersistence = driver.BindingStore

type SignerInfoPersistence = driver.SignerInfoStore

type AuditInfoPersistence = driver.AuditInfoStore

type BasePersistence[V any, R any] interface {
// SetState sets the given value for the given namespace, key, and version
SetState(namespace driver.Namespace, key driver.PKey, value V) error
Expand Down Expand Up @@ -154,6 +156,8 @@ type Driver interface {
NewBinding(dataSourceName string, config Config) (BindingPersistence, error)
// NewSignerInfo returns a new SignerInfoPersistence for the passed data source and config
NewSignerInfo(string, Config) (SignerInfoPersistence, error)
// NewAuditInfo returns a new AuditInfoPersistence for the passed data source and config
NewAuditInfo(string, Config) (AuditInfoPersistence, error)
}

type (
Expand Down
4 changes: 4 additions & 0 deletions platform/view/services/db/driver/memory/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,7 @@ func (d *Driver) NewBinding(string, driver.Config) (driver.BindingPersistence, e
func (d *Driver) NewSignerInfo(string, driver.Config) (driver.SignerInfoPersistence, error) {
return sql.NewPersistenceWithOpts(utils.GenerateUUIDOnlyLetters(), opts, sql.SignerInfoConstructors)
}

func (d *Driver) NewAuditInfo(string, driver.Config) (driver.AuditInfoPersistence, error) {
return sql.NewPersistenceWithOpts(utils.GenerateUUIDOnlyLetters(), opts, sql.AuditInfoConstructors)
}
65 changes: 65 additions & 0 deletions platform/view/services/db/driver/sql/common/auditinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package common

import (
"database/sql"
"fmt"

"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
"github.com/pkg/errors"
)

func NewAuditInfoPersistence(writeDB *sql.DB, readDB *sql.DB, table string, errorWrapper driver.SQLErrorWrapper, ci Interpreter) *AuditInfoPersistence {
return &AuditInfoPersistence{
table: table,
errorWrapper: errorWrapper,
readDB: readDB,
writeDB: writeDB,
ci: ci,
}
}

type AuditInfoPersistence struct {
table string
errorWrapper driver.SQLErrorWrapper
readDB *sql.DB
writeDB *sql.DB
ci Interpreter
}

func (db *AuditInfoPersistence) GetAuditInfo(id view.Identity) ([]byte, error) {
where, params := Where(db.ci.Cmp("id", "=", id.UniqueID()))
query := fmt.Sprintf("SELECT audit_info FROM %s %s", db.table, where)
logger.Debug(query, params)

return QueryUnique[[]byte](db.readDB, query, params...)
}

func (db *AuditInfoPersistence) PutAuditInfo(id view.Identity, info []byte) error {
query := fmt.Sprintf("INSERT INTO %s (id, audit_info) VALUES ($1, $2)", db.table)
logger.Debugf(query, id, info)
_, err := db.writeDB.Exec(query, id.UniqueID(), info)
if err != nil && errors.Is(db.errorWrapper.WrapError(err), driver.UniqueKeyViolation) {
logger.Warnf("Audit info [%s] already in db. Skipping...", id)
return nil
}
if err != nil {
return errors.Wrapf(err, "failed executing query [%s]", query)
}
logger.Debugf("Signer [%s] registered", id)
return nil
}

func (db *AuditInfoPersistence) CreateSchema() error {
return InitSchema(db.writeDB, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %s (
id TEXT NOT NULL PRIMARY KEY,
audit_info BYTEA NOT NULL
);`, db.table))
}
18 changes: 18 additions & 0 deletions platform/view/services/db/driver/sql/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ type signerInfoPersistence interface {
dbObject
}

type auditInfoPersistence interface {
driver.AuditInfoPersistence
dbObject
}

var UnversionedConstructors = map[common.SQLDriverType]persistenceConstructor[unversionedPersistence]{
Postgres: func(o common.Opts, t string) (unversionedPersistence, error) { return postgres.NewUnversioned(o, t) },
SQLite: func(o common.Opts, t string) (unversionedPersistence, error) { return sqlite.NewUnversioned(o, t) },
Expand All @@ -92,6 +97,15 @@ var SignerInfoConstructors = map[common.SQLDriverType]persistenceConstructor[sig
},
}

var AuditInfoConstructors = map[common.SQLDriverType]persistenceConstructor[auditInfoPersistence]{
Postgres: func(o common.Opts, t string) (auditInfoPersistence, error) {
return postgres.NewAuditInfoPersistence(o, t)
},
SQLite: func(o common.Opts, t string) (auditInfoPersistence, error) {
return sqlite.NewAuditInfoPersistence(o, t)
},
}

func (d *Driver) NewVersioned(dataSourceName string, config driver.Config) (driver.VersionedPersistence, error) {
return d.NewTransactionalVersioned(dataSourceName, config)
}
Expand Down Expand Up @@ -120,6 +134,10 @@ func (d *Driver) NewSignerInfo(dataSourceName string, config driver.Config) (dri
return newPersistence(dataSourceName, config, SignerInfoConstructors)
}

func (d *Driver) NewAuditInfo(dataSourceName string, config driver.Config) (driver.AuditInfoPersistence, error) {
return newPersistence(dataSourceName, config, AuditInfoConstructors)
}

func newPersistence[V dbObject](dataSourceName string, config driver.Config, constructors map[common.SQLDriverType]persistenceConstructor[V]) (V, error) {
logger.Infof("opening new transactional database %s", dataSourceName)
opts, err := getOps(config)
Expand Down
30 changes: 30 additions & 0 deletions platform/view/services/db/driver/sql/postgres/auditinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package postgres

import (
"database/sql"
"fmt"

"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/sql/common"
)

type AuditInfoPersistence struct {
*common.AuditInfoPersistence
}

func NewAuditInfoPersistence(opts common.Opts, table string) (*AuditInfoPersistence, error) {
readWriteDB, err := OpenDB(opts.DataSource, opts.MaxOpenConns, opts.MaxIdleConns, opts.MaxIdleTime)
if err != nil {
return nil, fmt.Errorf("error opening db: %w", err)
}
return newAuditInfoPersistence(readWriteDB, readWriteDB, table), nil
}

func newAuditInfoPersistence(readDB, writeDB *sql.DB, table string) *AuditInfoPersistence {
return &AuditInfoPersistence{AuditInfoPersistence: common.NewAuditInfoPersistence(readDB, writeDB, table, &errorMapper{}, NewInterpreter())}
}
4 changes: 4 additions & 0 deletions platform/view/services/db/driver/sql/postgres/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,7 @@ func (t *TestDriver) NewBinding(dataSourceName string, config driver.Config) (dr
func (t *TestDriver) NewSignerInfo(string, driver.Config) (driver.SignerInfoPersistence, error) {
return initPersistence(NewSignerInfoPersistence, t.ConnStr, t.Name, 50, 10, time.Minute)
}

func (t *TestDriver) NewAuditInfo(string, driver.Config) (driver.AuditInfoPersistence, error) {
return initPersistence(NewAuditInfoPersistence, t.ConnStr, t.Name, 50, 10, time.Minute)
}
30 changes: 30 additions & 0 deletions platform/view/services/db/driver/sql/sqlite/auditinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package sqlite

import (
"database/sql"
"fmt"

"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver/sql/common"
)

type AuditInfoPersistence struct {
*common.AuditInfoPersistence
}

func NewAuditInfoPersistence(opts common.Opts, table string) (*AuditInfoPersistence, error) {
readDB, writeDB, err := openDB(opts.DataSource, opts.MaxOpenConns, opts.MaxIdleConns, opts.MaxIdleTime, opts.SkipPragmas)
if err != nil {
return nil, fmt.Errorf("error opening db: %w", err)
}
return newAuditInfoPersistence(readDB, writeDB, table), nil
}

func newAuditInfoPersistence(readDB, writeDB *sql.DB, table string) *AuditInfoPersistence {
return &AuditInfoPersistence{AuditInfoPersistence: common.NewAuditInfoPersistence(readDB, writeDB, table, &errorMapper{}, NewInterpreter())}
}
4 changes: 4 additions & 0 deletions platform/view/services/db/driver/sql/sqlite/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func (t *TestDriver) NewSignerInfo(string, driver.Config) (driver.SignerInfoPers
return NewSignerInfoPersistence(unversionedOpts(t.Name, t.TempDir), "test")
}

func (t *TestDriver) NewAuditInfo(string, driver.Config) (driver.AuditInfoPersistence, error) {
return NewAuditInfoPersistence(unversionedOpts(t.Name, t.TempDir), "test")
}

func unversionedOpts(name string, tempDir string) common2.Opts {
maxIdleConns, maxIdleTime := 2, 1*time.Minute
return common2.Opts{DataSource: fmt.Sprintf("file:%s.sqlite?_pragma=busy_timeout(1000)", path.Join(tempDir, name)), MaxIdleConns: &maxIdleConns, MaxIdleTime: &maxIdleTime}
Expand Down
20 changes: 20 additions & 0 deletions platform/view/services/storage/auditinfo/standalone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package auditinfo

import (
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/db/driver"
)

const (
persistenceOptsConfigKey = "fsc.auditinfo.persistence.opts"
)

func NewWithConfig(dbDriver driver.Driver, namespace string, cp db.Config) (driver.AuditInfoPersistence, error) {
return dbDriver.NewAuditInfo(namespace, db.NewPrefixConfig(cp, persistenceOptsConfigKey))
}

0 comments on commit 8ed155a

Please sign in to comment.