Skip to content

Commit 9a40f01

Browse files
feat: add database configuration for databaseID (#479)
* feat: add database configuration for databaseID * chore: fix test name typo
1 parent 2b8f030 commit 9a40f01

5 files changed

Lines changed: 56 additions & 24 deletions

File tree

configs/service.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ trace_service_name: "open-saves"
3535
trace_sample_rate: 0.00
3636

3737
datastore_tx_max_attempts: 2
38+
datastore_database_id: ""

internal/pkg/config/loader.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func Load(path string) (*ServiceConfig, error) {
152152

153153
datastoreConfig := DatastoreConfig{
154154
TXMaxAttempts: viper.GetInt(DatastoreTXMaxAttempts),
155+
DatabaseId: viper.GetString(DatastoreDatabaseId),
155156
}
156157

157158
return &ServiceConfig{

internal/pkg/config/model.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const (
5757
TraceEnableHTTPCollector = "trace_enable_http_collector"
5858

5959
DatastoreTXMaxAttempts = "datastore_tx_max_attempts"
60+
DatastoreDatabaseId = "datastore_database_id"
6061
)
6162

6263
type ServiceConfig struct {
@@ -131,4 +132,5 @@ type GRPCServerConfig struct {
131132

132133
type DatastoreConfig struct {
133134
TXMaxAttempts int
135+
DatabaseId string
134136
}

internal/pkg/metadb/metadb.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ const (
5151
ownerField = "OwnerID"
5252
)
5353

54-
var (
55-
ErrNoUpdate = errors.New("UpdateRecord doesn't need to commit the change")
56-
)
54+
var ErrNoUpdate = errors.New("UpdateRecord doesn't need to commit the change")
5755

5856
// MetaDB is a metadata database manager of Open Saves.
5957
// The methods return gRPC error codes. Here are some common error codes
@@ -87,7 +85,7 @@ func removeInlineBlob(r *record.Record) *record.Record {
8785

8886
// NewMetaDB creates a new MetaDB instance with an initialized database client.
8987
func NewMetaDB(ctx context.Context, projectID string, config config.DatastoreConfig, opts ...option.ClientOption) (*MetaDB, error) {
90-
client, err := ds.NewClient(ctx, projectID, opts...)
88+
client, err := ds.NewClientWithDatabase(ctx, projectID, config.DatabaseId, opts...)
9189
if err != nil {
9290
return nil, datastoreErrToGRPCStatus(err)
9391
}
@@ -148,7 +146,8 @@ func (m *MetaDB) getBlobRef(ctx context.Context, tx *ds.Transaction, key uuid.UU
148146

149147
// Returns a modified Record and the caller must commit the change.
150148
func (m *MetaDB) markBlobRefForDeletion(tx *ds.Transaction,
151-
record *record.Record, blob *blobref.BlobRef, newBlobKey uuid.UUID) (*record.Record, error) {
149+
record *record.Record, blob *blobref.BlobRef, newBlobKey uuid.UUID,
150+
) (*record.Record, error) {
152151
if record.ExternalBlob == uuid.Nil {
153152
return nil, status.Error(codes.FailedPrecondition, "the record doesn't have an external blob associated")
154153
}
@@ -354,8 +353,8 @@ func (m *MetaDB) UpdateRecord(ctx context.Context, storeKey string, key string,
354353
if err != nil {
355354
return err
356355
}
357-
// Update the external blob with the new ExpiresAt coming from the record.
358-
// Will update only if the incoming update changes the expiresAt value and it differs from the oldBlob one.
356+
// Update the external blob with the new ExpiresAt coming from the record.
357+
// Will update only if the incoming update changes the expiresAt value and it differs from the oldBlob one.
359358
} else if !toUpdate.ExpiresAt.IsZero() && oldBlob.ExpiresAt != toUpdate.ExpiresAt {
360359
oldBlob.ExpiresAt = toUpdate.ExpiresAt
361360
err = m.mutateSingleInTransaction(tx, ds.NewUpdate(m.createBlobKey(toUpdate.ExternalBlob), oldBlob))
@@ -459,7 +458,6 @@ func (m *MetaDB) UpdateBlobRef(ctx context.Context, blob *blobref.BlobRef) (*blo
459458
_, err = tx.Mutate(mut)
460459
return err
461460
}, datastore.MaxAttempts(m.config.TXMaxAttempts))
462-
463461
if err != nil {
464462
return nil, datastoreErrToGRPCStatus(err)
465463
}
@@ -1096,7 +1094,6 @@ func (m *MetaDB) InsertChunkRef(ctx context.Context, blob *blobref.BlobRef, chun
10961094
defer span.End()
10971095

10981096
_, err := m.client.RunInTransaction(ctx, func(tx *ds.Transaction) error {
1099-
11001097
mut := ds.NewInsert(m.createChunkRefKey(chunk.BlobRef, chunk.Key), chunk)
11011098
if err := m.mutateSingleInTransaction(tx, mut); err != nil {
11021099
return err

internal/pkg/metadb/metadb_test.go

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ const (
5050
testNamespace = "datastore-unittests"
5151
)
5252

53-
var defaultDatastoreConfig = config.DatastoreConfig{TXMaxAttempts: 1}
53+
var (
54+
defaultDatastoreConfig = config.DatastoreConfig{TXMaxAttempts: 1}
55+
datastoreConfigWithId = config.DatastoreConfig{TXMaxAttempts: 1, DatabaseId: "database-id"}
56+
)
5457

5558
func getTestProject() string {
5659
if testProject, ok := os.LookupEnv("TEST_PROJECT_ID"); ok {
@@ -91,6 +94,17 @@ func newMetaDB(ctx context.Context, t *testing.T) *m.MetaDB {
9194
return metaDB
9295
}
9396

97+
func newMetaDBWithDatabaseConfig(ctx context.Context, t *testing.T) *m.MetaDB {
98+
t.Helper()
99+
metaDB, err := m.NewMetaDB(ctx, getTestProject(), datastoreConfigWithId)
100+
if err != nil {
101+
t.Fatalf("Initializing MetaDB with DatabaseId: %v", err)
102+
}
103+
metaDB.Namespace = testNamespace
104+
t.Cleanup(func() { metaDB.Disconnect(ctx) })
105+
return metaDB
106+
}
107+
94108
func newStoreKey() string {
95109
return uuid.NewString() + "_unittest_store"
96110
}
@@ -226,6 +240,15 @@ func setupTestStoreRecordBlobSet(ctx context.Context, t *testing.T, metaDB *m.Me
226240
return store, record, blob
227241
}
228242

243+
func TestMetaDB_WithDatabaseIDErrorGettingRecord(t *testing.T) {
244+
ctx := context.Background()
245+
metaDB := newMetaDBWithDatabaseConfig(ctx, t)
246+
247+
record, err := metaDB.GetRecord(ctx, newStoreKey(), newRecordKey())
248+
assert.Nil(t, record, "GetRecord() should be nil")
249+
assert.Error(t, err, "GetRecord() should return error when database is unknown")
250+
}
251+
229252
func TestMetaDB_Disconnect(t *testing.T) {
230253
ctx := context.Background()
231254
metaDB := newMetaDB(ctx, t)
@@ -762,7 +785,7 @@ func TestMetaDB_UpdateRecordWithExternalBlobs(t *testing.T) {
762785
}
763786

764787
recordKey := newRecordKey()
765-
expiresAt := time.Now().UTC().Add(3*time.Hour).Truncate(time.Hour)
788+
expiresAt := time.Now().UTC().Add(3 * time.Hour).Truncate(time.Hour)
766789
origRecord := &record.Record{
767790
Key: recordKey,
768791
Properties: make(record.PropertyMap),
@@ -818,7 +841,7 @@ func TestMetaDB_UpdateRecordWithExternalBlobs(t *testing.T) {
818841
}
819842

820843
// Make sure ExpiresAt is updated in the BlobRef when updated in the Record.
821-
newExpiresAt := time.Now().UTC().Add(6*time.Hour).Truncate(time.Hour)
844+
newExpiresAt := time.Now().UTC().Add(6 * time.Hour).Truncate(time.Hour)
822845
newRecord, err = metaDB.UpdateRecord(ctx, storeKey, recordKey, func(record *record.Record) (*record.Record, error) {
823846
record.ExpiresAt = newExpiresAt
824847
return record, nil
@@ -890,7 +913,8 @@ func TestMetaDB_ListBlobsByStatus(t *testing.T) {
890913
blobref.StatusError,
891914
blobref.StatusInitializing,
892915
blobref.StatusPendingDeletion,
893-
blobref.StatusPendingDeletion}
916+
blobref.StatusPendingDeletion,
917+
}
894918
for _, s := range statuses {
895919
blob := &blobref.BlobRef{
896920
Key: uuid.New(),
@@ -1214,7 +1238,8 @@ func TestMetaDB_QueryRecords(t *testing.T) {
12141238
StoreKey: stores[0].Key,
12151239
OwnerId: "abc",
12161240
},
1217-
[]*record.Record{records[0]}, codes.OK,
1241+
[]*record.Record{records[0]},
1242+
codes.OK,
12181243
},
12191244
{
12201245
"Tags AND No Result",
@@ -1227,27 +1252,29 @@ func TestMetaDB_QueryRecords(t *testing.T) {
12271252
{
12281253
"Tags OR No Result",
12291254
&pb.QueryRecordsRequest{
1230-
StoreKey: stores[1].Key,
1231-
Tags: []string{"non-existing-tag-1", "non-existing-tag-2"},
1255+
StoreKey: stores[1].Key,
1256+
Tags: []string{"non-existing-tag-1", "non-existing-tag-2"},
12321257
TagFilterMode: pb.TagFilterMode_OR,
12331258
},
12341259
nil, codes.OK,
12351260
},
12361261
{
12371262
"Tags OR",
12381263
&pb.QueryRecordsRequest{
1239-
StoreKey: stores[1].Key,
1240-
Tags: []string{tag1, tag4},
1264+
StoreKey: stores[1].Key,
1265+
Tags: []string{tag1, tag4},
12411266
TagFilterMode: pb.TagFilterMode_OR,
12421267
},
1243-
[]*record.Record{records[2]}, codes.OK,
1268+
[]*record.Record{records[2]},
1269+
codes.OK,
12441270
},
12451271
{
12461272
"Tags Multiple Records",
12471273
&pb.QueryRecordsRequest{
12481274
Tags: []string{tag1},
12491275
},
1250-
[]*record.Record{records[0], records[2]}, codes.OK,
1276+
[]*record.Record{records[0], records[2]},
1277+
codes.OK,
12511278
},
12521279
{
12531280
"Limit",
@@ -1256,23 +1283,26 @@ func TestMetaDB_QueryRecords(t *testing.T) {
12561283
Tags: []string{tag1},
12571284
Limit: 1,
12581285
},
1259-
[]*record.Record{records[0]}, codes.OK,
1286+
[]*record.Record{records[0]},
1287+
codes.OK,
12601288
},
12611289
{
12621290
"Limit No Filtering",
12631291
&pb.QueryRecordsRequest{
12641292
StoreKey: stores[0].Key,
12651293
Limit: 1,
12661294
},
1267-
[]*record.Record{records[0]}, codes.OK,
1295+
[]*record.Record{records[0]},
1296+
codes.OK,
12681297
},
12691298
{
12701299
"Offset No Filtering",
12711300
&pb.QueryRecordsRequest{
12721301
StoreKey: stores[0].Key,
12731302
Offset: 1,
12741303
},
1275-
[]*record.Record{records[1]}, codes.OK,
1304+
[]*record.Record{records[1]},
1305+
codes.OK,
12761306
},
12771307
{
12781308
"Keys Only",
@@ -1282,7 +1312,8 @@ func TestMetaDB_QueryRecords(t *testing.T) {
12821312
Tags: []string{tag1},
12831313
KeysOnly: true,
12841314
},
1285-
[]*record.Record{{Key: records[0].Key, StoreKey: records[0].StoreKey}}, codes.OK,
1315+
[]*record.Record{{Key: records[0].Key, StoreKey: records[0].StoreKey}},
1316+
codes.OK,
12861317
},
12871318
}
12881319
for _, tc := range testCases {

0 commit comments

Comments
 (0)