Skip to content

Commit 1b34f67

Browse files
committed
Merge remote-tracking branch 'origin/main' into CBG-5499
2 parents 602eb0e + 18ff852 commit 1b34f67

76 files changed

Lines changed: 1983 additions & 2452 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

auth/auth_test.go

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,17 +2838,12 @@ func TestInvalidateRoles(t *testing.T) {
28382838
err = auth.InvalidateRoles("user", 10)
28392839
assert.NoError(t, err)
28402840

2841-
// Ensure the inval seq was set to 5 (raw get to avoid rebuild)
2841+
// Ensure the inval seq was set to 10 (raw get to avoid rebuild)
28422842
var userOut userImpl
28432843
_, err = leakyDataStore.Get(ctx, auth.DocIDForUser("user"), &userOut)
28442844
assert.NoError(t, err)
28452845

2846-
var expectedValue uint64
2847-
if leakyBucket.IsSupported(sgbucket.BucketStoreFeatureSubdocOperations) {
2848-
expectedValue = 10
2849-
} else {
2850-
expectedValue = 5
2851-
}
2846+
expectedValue := uint64(10)
28522847

28532848
assert.Equal(t, expectedValue, userOut.GetRoleInvalSeq())
28542849

@@ -2905,24 +2900,9 @@ func TestInvalidateChannels(t *testing.T) {
29052900
assert.NoError(t, err)
29062901

29072902
// Invalidate channels at invalSeq but cause cas retry by setting to 5
2908-
enableRetry := false
2909-
// If subdoc operations are supported, perform an initial invalidation at seq 5
2910-
if leakyBucket.IsSupported(sgbucket.BucketStoreFeatureSubdocOperations) {
2911-
err := auth.InvalidateDefaultChannels(testCase.name, testCase.isUser, 5)
2912-
assert.NoError(t, err)
2913-
2914-
} else {
2915-
// If subdoc ops aren't supported, use leakyBucket to invalidate
2916-
leakyDataStore.SetUpdateCallback(func(key string) {
2917-
if enableRetry {
2918-
enableRetry = false
2919-
err = auth.InvalidateDefaultChannels(testCase.name, testCase.isUser, 5)
2920-
assert.NoError(t, err)
2921-
}
2922-
})
2923-
}
2903+
err = auth.InvalidateDefaultChannels(testCase.name, testCase.isUser, 5)
2904+
assert.NoError(t, err)
29242905

2925-
enableRetry = true
29262906
err = auth.InvalidateDefaultChannels(testCase.name, testCase.isUser, 10)
29272907
assert.NoError(t, err)
29282908

base/bootstrap.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ type BootstrapConnection interface {
5252
// for the given bucket; subsequent bootstrap reads for that bucket stop falling back to
5353
// _default._default. Per-bucket so completing one bucket never disables another's fallback.
5454
SetMigrationComplete(bucketName string)
55+
// IsMigrationComplete reports whether this process has marked bootstrap-metadata migration complete for the given bucket (local cache).
56+
IsMigrationComplete(bucketName string) bool
5557
// GetMetadataMigrationStatus reads the bucket-level metadata-migration status doc directly from
5658
// _system._mobile (never via the dual-collection wrapper). Returns ErrNotFound when the doc has
5759
// not yet been stamped on this bucket.
@@ -108,7 +110,6 @@ type CouchbaseClusterSpec struct {
108110
type CouchbaseCluster struct {
109111
server string
110112
clusterOptions gocb.ClusterOptions
111-
forcePerBucketAuth bool // Forces perBucketAuth authenticators to be used to connect to the bucket
112113
perBucketAuth map[string]*gocb.Authenticator
113114
bucketConnectionMode BucketConnectionMode // Whether to cache cluster connections
114115
cachedClusterConnection *gocb.Cluster // Cached cluster connection, should only be used by GetConfigBuckets
@@ -234,7 +235,7 @@ var _ BootstrapConnection = &CouchbaseCluster{}
234235
// _system._mobile is the source of truth and reads transparently fall back to _default._default
235236
// for any keys that have not yet been migrated; when false, _default._default is used unconditionally.
236237
func NewCouchbaseCluster(ctx context.Context, clusterSpec CouchbaseClusterSpec,
237-
forcePerBucketAuth bool, perBucketCreds PerBucketCredentialsConfig,
238+
perBucketCreds PerBucketCredentialsConfig,
238239
useXattrConfig bool, useSystemMetadataCollection bool, bucketMode BucketConnectionMode) (*CouchbaseCluster, error) {
239240
securityConfig, err := GoCBv2SecurityConfig(ctx, Ptr(clusterSpec.TLSSkipVerify), clusterSpec.CACertpath)
240241
if err != nil {
@@ -271,7 +272,6 @@ func NewCouchbaseCluster(ctx context.Context, clusterSpec CouchbaseClusterSpec,
271272

272273
cbCluster := &CouchbaseCluster{
273274
server: clusterSpec.Server,
274-
forcePerBucketAuth: forcePerBucketAuth,
275275
perBucketAuth: perBucketAuth,
276276
clusterOptions: clusterOptions,
277277
bucketConnectionMode: bucketMode,
@@ -511,6 +511,10 @@ func (cc *CouchbaseCluster) SetMigrationComplete(bucketName string) {
511511
cc.bucketsBootstrapMigrationComplete.Store(bucketName, true)
512512
}
513513

514+
func (cc *CouchbaseCluster) IsMigrationComplete(bucketName string) bool {
515+
return cc.bucketBootstrapMigrationComplete(bucketName)
516+
}
517+
514518
// bucketBootstrapMigrationComplete reports whether bootstrap-metadata migration has been marked
515519
// complete for the given bucket. Absence of an entry means not-complete, so reads keep the
516520
// _default._default fallback.
@@ -1109,8 +1113,6 @@ func defaultCollectionExists(b *gocb.Bucket) (bool, error) {
11091113
func (cc *CouchbaseCluster) GetClusterConnectionForBucket(ctx context.Context, bucketName string) (connection *gocb.Cluster, teardownFn func(), err error) {
11101114
if bucketAuth, set := cc.perBucketAuth[bucketName]; set {
11111115
connection, err = cc.connect(bucketAuth)
1112-
} else if cc.forcePerBucketAuth {
1113-
return nil, nil, fmt.Errorf("unable to get bucket %q since credentials are not defined in bucket_credentials", MD(bucketName).Redact())
11141116
} else {
11151117
connection, err = cc.connect(nil)
11161118
}

base/bootstrap_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ func TestBootstrapRefCounting(t *testing.T) {
5353
}, 2*time.Minute, 5*time.Millisecond) // Wait for bucket pool to be initialized, since GetConfigBuckets requires equal buckets to TestBucketPool.numBuckets
5454

5555
var perBucketCredentialsConfig map[string]*CredentialsConfig
56-
forcePerBucketAuth := false
57-
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), forcePerBucketAuth, perBucketCredentialsConfig, TestUseXattrs(), false, CachedClusterConnections)
56+
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), perBucketCredentialsConfig, TestUseXattrs(), false, CachedClusterConnections)
5857
require.NoError(t, err)
5958
defer cluster.Close()
6059
require.NotNil(t, cluster)
@@ -146,7 +145,7 @@ func newTestBootstrapConnection(t *testing.T) BootstrapConnection {
146145
t.Cleanup(cluster.Close)
147146
return cluster
148147
}
149-
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), false, nil, TestUseXattrs(), false, CachedClusterConnections)
148+
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), nil, TestUseXattrs(), false, CachedClusterConnections)
150149
require.NoError(t, err)
151150
t.Cleanup(cluster.Close)
152151
return cluster
@@ -360,7 +359,7 @@ func newCouchbaseBootstrapDualFixture(t *testing.T, useXattrs bool) bootstrapDua
360359
assert.Equal(c, int32(GTestBucketPool.numBuckets), GTestBucketPool.stats.TotalBucketInitCount.Load())
361360
}, 2*time.Minute, 5*time.Millisecond)
362361

363-
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), false, nil, useXattrs, true, CachedClusterConnections)
362+
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), nil, useXattrs, true, CachedClusterConnections)
364363
require.NoError(t, err)
365364
t.Cleanup(cluster.Close)
366365

@@ -469,7 +468,7 @@ func newCouchbaseBootstrapTwoBucketDualFixture(t *testing.T, useXattrs bool) boo
469468
assert.Equal(c, int32(GTestBucketPool.numBuckets), GTestBucketPool.stats.TotalBucketInitCount.Load())
470469
}, 2*time.Minute, 5*time.Millisecond)
471470

472-
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), false, nil, useXattrs, true, CachedClusterConnections)
471+
cluster, err := NewCouchbaseCluster(ctx, TestClusterSpec(t), nil, useXattrs, true, CachedClusterConnections)
473472
require.NoError(t, err)
474473
t.Cleanup(cluster.Close)
475474

base/bucket.go

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ type BucketSpec struct {
116116
Auth AuthHandler
117117
Certpath, Keypath, CACertPath string // X.509 auth parameters
118118
TLSSkipVerify bool // Use insecureSkipVerify when secure scheme (couchbases) is used and cacertpath is undefined
119-
KvTLSPort int // Port to use for memcached over TLS. Required for cbdatasource auth when using TLS
120-
UseXattrs bool // Whether to use xattrs to store _sync metadata. Used during view initialization
121119
ViewQueryTimeoutSecs *uint32 // the view query timeout in seconds (default: 75 seconds)
122120
MaxConcurrentQueryOps *int // maximum number of concurrent query operations (default: DefaultMaxConcurrentQueryOps)
123121
BucketOpTimeout *time.Duration // How long bucket ops should block returning "operation timed out". If nil, uses GoCB default. GoCB buckets only.
@@ -302,16 +300,6 @@ func GetBucket(ctx context.Context, spec BucketSpec) (bucket Bucket, err error)
302300
if err != nil {
303301
return nil, err
304302
}
305-
306-
// If XATTRS are enabled via enable_shared_bucket_access config flag, assert that Couchbase Server is 5.0
307-
// or later, otherwise refuse to connect to the bucket since pre 5.0 versions don't support XATTRs
308-
if spec.UseXattrs {
309-
if !bucket.IsSupported(sgbucket.BucketStoreFeatureXattrs) {
310-
WarnfCtx(ctx, "If using XATTRS, Couchbase Server version must be >= 5.0.")
311-
return nil, ErrFatalBucketConnection
312-
}
313-
}
314-
315303
}
316304

317305
// TODO: CBG-2529 - LoggingBucket has been removed - pending a new approach to logging all bucket operations
@@ -469,10 +457,10 @@ func AsViewStore(ds DataStore) (sgbucket.ViewStore, bool) {
469457
return viewStore, ok
470458
}
471459

472-
// AsSubdocStore returns a SubdocStore if the underlying dataStore implements and supports subdoc operations.
460+
// AsSubdocStore returns a SubdocStore if the underlying dataStore implements subdoc operations.
473461
func AsSubdocStore(ds DataStore) (sgbucket.SubdocStore, bool) {
474462
subdocStore, ok := ds.(sgbucket.SubdocStore)
475-
return subdocStore, ok && ds.IsSupported(sgbucket.BucketStoreFeatureSubdocOperations)
463+
return subdocStore, ok
476464
}
477465

478466
// AsRangeScanStore returns a RangeScanStore if the dataStore implements and supports range scan operations.

base/bucket_gocb_test.go

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -725,27 +725,13 @@ func TestMultiXattrRoundtrip(t *testing.T) {
725725
xattrKeys[2]: []byte(`{"key3": "value3"}`),
726726
}
727727
_, err := dataStore.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"key": "value"}`), inputXattrs, nil, nil)
728-
if dataStore.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
729-
require.NoError(t, err)
730-
} else {
731-
require.ErrorContains(t, err, "invalid xattr key combination")
732-
inputXattrs = map[string][]byte{
733-
xattrKeys[0]: inputXattrs[xattrKeys[0]],
734-
}
735-
// write a document an xattrs, because subsequent GetXattrs needs a document to produce an error without multi-xattr support
736-
_, err := dataStore.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"key": "value"}`), inputXattrs, nil, nil)
737-
require.NoError(t, err)
738-
}
728+
require.NoError(t, err)
739729

740730
xattrs, _, err := dataStore.GetXattrs(ctx, docID, xattrKeys)
741-
if dataStore.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
742-
require.NoError(t, err)
743-
for _, key := range xattrKeys {
744-
require.Contains(t, maps.Keys(xattrs), key)
745-
require.JSONEq(t, string(inputXattrs[key]), string(xattrs[key]))
746-
}
747-
} else {
748-
require.ErrorContains(t, err, "not supported")
731+
require.NoError(t, err)
732+
for _, key := range xattrKeys {
733+
require.Contains(t, maps.Keys(xattrs), key)
734+
require.JSONEq(t, string(inputXattrs[key]), string(xattrs[key]))
749735
}
750736
}
751737

@@ -2325,15 +2311,8 @@ func TestUserXattrGetWithXattr(t *testing.T) {
23252311
"_sync": MustJSONMarshal(t, syncXattrVal),
23262312
"test": MustJSONMarshal(t, userXattrVal),
23272313
}
2328-
if bucket.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
2329-
_, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, xattrs, nil)
2330-
require.NoError(t, err)
2331-
} else {
2332-
for k, v := range xattrs {
2333-
cas, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, map[string][]byte{k: v}, nil)
2334-
require.NoError(t, err)
2335-
}
2336-
}
2314+
_, err = dataStore.UpdateXattrs(ctx, docKey, 0, cas, xattrs, nil)
2315+
require.NoError(t, err)
23372316
var docValRet map[string]any
23382317
docRaw, xattrsResult, _, err := dataStore.GetWithXattrs(ctx, docKey, []string{SyncXattrName, "test"})
23392318
require.NoError(t, JSONUnmarshal(docRaw, &docValRet))
@@ -2549,9 +2528,6 @@ func TestUpsertOptionPreserveExpiry(t *testing.T) {
25492528
bucket := GetTestBucket(t)
25502529
defer bucket.Close(ctx)
25512530
dataStore := bucket.GetSingleDataStore()
2552-
if !bucket.IsSupported(sgbucket.BucketStoreFeaturePreserveExpiry) {
2553-
t.Skip("Preserve expiry is not supported with this CBS version. Skipping test...")
2554-
}
25552531

25562532
testCases := []struct {
25572533
name string
@@ -2676,11 +2652,6 @@ func TestWriteWithXattrsBodyUpdateXattrDelete(t *testing.T) {
26762652
xattrBody := []byte(`{"some": "val"}`)
26772653

26782654
cas, err := collection.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"foo": "bar"}`), map[string][]byte{xattr1Name: xattrBody, xattr2Name: xattrBody}, nil, nil)
2679-
// in Couchbase Server < 7.6, this will return an error because this is writing two xattrs
2680-
if !collection.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
2681-
require.ErrorContains(t, err, "SUBDOC_XATTR_INVALID_KEY_COMBO")
2682-
return
2683-
}
26842655
require.NoError(t, err)
26852656

26862657
_, err = collection.WriteWithXattrs(ctx, docID, 0, cas, []byte(`{"foo": "baz"}`), nil, []string{xattr1Name}, nil)
@@ -2706,10 +2677,6 @@ func TestWriteWithXattrsXattrWriteXattrDelete(t *testing.T) {
27062677
xattrBody := []byte(`{"some": "val"}`)
27072678

27082679
cas, err := collection.WriteWithXattrs(ctx, docID, 0, 0, []byte(`{"foo": "bar"}`), map[string][]byte{xattr1Name: xattrBody, xattr2Name: xattrBody}, nil, nil)
2709-
if !collection.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
2710-
require.ErrorContains(t, err, "SUBDOC_XATTR_INVALID_KEY_COMBO")
2711-
return
2712-
}
27132680
require.NoError(t, err)
27142681

27152682
newXattrBody := []byte(`{"another" : "val"}`)
@@ -2746,9 +2713,6 @@ func TestWriteUpdateWithXattrsDocumentTombstone(t *testing.T) {
27462713

27472714
bucket := GetTestBucket(t)
27482715
defer bucket.Close(ctx)
2749-
if !bucket.IsSupported(sgbucket.BucketStoreFeatureMultiXattrSubdocOperations) {
2750-
t.Skip("this test writes multiple xattrs")
2751-
}
27522716
dataStore := bucket.GetSingleDataStore()
27532717
key := t.Name()
27542718

base/collection.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,9 +645,6 @@ func (b *GocbV2Bucket) releaseQueryOp() {
645645
}
646646

647647
func (b *GocbV2Bucket) ListDataStores(_ context.Context) ([]sgbucket.DataStoreName, error) {
648-
if !b.IsSupported(sgbucket.BucketStoreFeatureCollections) {
649-
return []sgbucket.DataStoreName{ScopeAndCollectionName{Scope: DefaultScope, Collection: DefaultCollection}}, nil
650-
}
651648
scopes, err := b.bucket.Collections().GetAllScopes(nil)
652649
if err != nil {
653650
return nil, err

base/collection_gocb.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -422,11 +422,9 @@ func (c *Collection) GetExpiry(ctx context.Context, k string) (expiry uint32, ge
422422
}
423423

424424
getMetaOptions := gocbcore.GetMetaOptions{
425-
Key: []byte(k),
426-
Deadline: c.Bucket.getBucketOpDeadline(),
427-
}
428-
if c.IsSupported(sgbucket.BucketStoreFeatureCollections) {
429-
getMetaOptions.CollectionID = c.GetCollectionID()
425+
Key: []byte(k),
426+
Deadline: c.Bucket.getBucketOpDeadline(),
427+
CollectionID: c.GetCollectionID(),
430428
}
431429

432430
wg := sync.WaitGroup{}
@@ -564,10 +562,6 @@ func (c *Collection) GetCollectionID() uint32 {
564562

565563
// setCollectionID sets private property of kv CollectionID.
566564
func (c *Collection) setCollectionID() error {
567-
if !c.IsSupported(sgbucket.BucketStoreFeatureCollections) {
568-
c.kvCollectionID = DefaultCollectionID
569-
return nil
570-
}
571565
// default collection has a known ID
572566
if c.IsDefaultScopeCollection() {
573567
c.kvCollectionID = DefaultCollectionID

base/collection_n1ql.go

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@ func IsMobileSystemCollection(dsn sgbucket.DataStoreName) bool {
4343

4444
// EscapedKeyspace returns the escaped fully-qualified identifier for the keyspace (e.g. `bucket`.`scope`.`collection`)
4545
func (c *Collection) EscapedKeyspace() string {
46-
if !c.IsSupported(sgbucket.BucketStoreFeatureCollections) {
47-
return fmt.Sprintf("`%s`", c.BucketName())
48-
}
4946
return fmt.Sprintf("`%s`.`%s`.`%s`", c.BucketName(), c.ScopeName(), c.CollectionName())
5047
}
5148

@@ -70,17 +67,12 @@ func (c *Collection) BucketName() string {
7067
}
7168

7269
func (c *Collection) indexManager() *indexManager {
73-
m := &indexManager{
70+
return &indexManager{
7471
bucketName: c.BucketName(),
7572
collectionName: c.CollectionName(),
7673
scopeName: c.ScopeName(),
74+
collection: c.Collection.QueryIndexes(),
7775
}
78-
if !c.IsSupported(sgbucket.BucketStoreFeatureCollections) {
79-
m.cluster = c.Bucket.cluster.QueryIndexes()
80-
} else {
81-
m.collection = c.Collection.QueryIndexes()
82-
}
83-
return m
8476
}
8577

8678
// IndexMetaKeyspaceID returns the value of keyspace_id for the system:indexes table for the collection.
@@ -181,13 +173,7 @@ func (b *GocbV2Bucket) runQuery(scopeName string, statement string, n1qlOptions
181173
n1qlOptions = &gocb.QueryOptions{}
182174
}
183175

184-
var queryResults *gocb.QueryResult
185-
var err error
186-
if b.IsSupported(sgbucket.BucketStoreFeatureCollections) {
187-
queryResults, err = b.bucket.Scope(scopeName).Query(statement, n1qlOptions)
188-
} else {
189-
queryResults, err = b.cluster.Query(statement, n1qlOptions)
190-
}
176+
queryResults, err := b.bucket.Scope(scopeName).Query(statement, n1qlOptions)
191177
// In the event that we get an error during query we should release a view op as Close() will not be called.
192178
if err != nil {
193179
b.releaseQueryOp()

0 commit comments

Comments
 (0)