Skip to content

Deprecate currentOp/collStats commands #1175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import org.bson.BsonDocument
import org.bson.BsonInt32
import org.bson.BsonString
import org.bson.codecs.BsonDocumentCodec
import org.bson.codecs.DocumentCodec
import spock.lang.IgnoreIf

import static com.mongodb.ClusterFixture.getBinding
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet
import static com.mongodb.ClusterFixture.serverVersionAtLeast
import static com.mongodb.ClusterFixture.serverVersionLessThan
import static java.util.Collections.singletonList

class CreateCollectionOperationSpecification extends OperationFunctionalSpecification {

Expand Down Expand Up @@ -160,9 +160,7 @@ class CreateCollectionOperationSpecification extends OperationFunctionalSpecific
collectionNameExists(getCollectionName())

when:
def stats = new CommandReadOperation<>(getDatabaseName(),
new BsonDocument('collStats', new BsonString(getCollectionName())),
new BsonDocumentCodec()).execute(getBinding())
def stats = storageStats()

then:
stats.getBoolean('capped').getValue()
Expand All @@ -186,10 +184,7 @@ class CreateCollectionOperationSpecification extends OperationFunctionalSpecific
execute(operation, async)

then:
new CommandReadOperation<>(getDatabaseName(),
new BsonDocument('collStats', new BsonString(getCollectionName())),
new DocumentCodec()).execute(getBinding())
.getInteger('nindexes') == expectedNumberOfIndexes
storageStats().getInt32('nindexes').intValue() == expectedNumberOfIndexes

where:
autoIndex | expectedNumberOfIndexes | async
Expand Down Expand Up @@ -291,4 +286,21 @@ class CreateCollectionOperationSpecification extends OperationFunctionalSpecific
def collectionNameExists(String collectionName) {
getCollectionInfo(collectionName) != null
}

BsonDocument storageStats() {
if (serverVersionLessThan(6, 2)) {
return new CommandReadOperation<>(getDatabaseName(),
new BsonDocument('collStats', new BsonString(getCollectionName())),
new BsonDocumentCodec()).execute(getBinding())
}
BatchCursor<BsonDocument> cursor = new AggregateOperation(
getNamespace(),
singletonList(new BsonDocument('$collStats', new BsonDocument('storageStats', new BsonDocument()))),
new BsonDocumentCodec()).execute(getBinding())
try {
return cursor.next().first().getDocument('storageStats')
} finally {
cursor.close()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
]
},
{
"description": "current op is not bypassed",
"description": "kill op is not bypassed",
"clientOptions": {
"autoEncryptOpts": {
"kmsProviders": {
Expand All @@ -90,14 +90,15 @@
{
"name": "runCommand",
"object": "database",
"command_name": "currentOp",
"command_name": "killOp",
"arguments": {
"command": {
"currentOp": 1
"killOp": 1,
"op": 1234
}
},
"result": {
"errorContains": "command not supported for auto encryption: currentOp"
"errorContains": "command not supported for auto encryption: killOp"
}
}
]
Expand Down
12 changes: 11 additions & 1 deletion driver-legacy/src/main/com/mongodb/DBCollection.java
Original file line number Diff line number Diff line change
Expand Up @@ -1914,7 +1914,12 @@ public void dropIndexes(final String indexName) {
*
* @return a CommandResult containing the statistics about this collection
* @mongodb.driver.manual reference/command/collStats/ collStats Command
* @mongodb.driver.manual reference/operator/aggregation/collStats/ $collStats
* @deprecated If you are using server release 3.4 or newer, use the {@code $collStats} aggregation pipeline stage via
* {@link #aggregate(List, AggregationOptions)} instead.
* This method uses the {@code collStats} command, which is deprecated since server release 6.2.
*/
@Deprecated
public CommandResult getStats() {
return getDB().executeCommand(new BsonDocument("collStats", new BsonString(getName())), getReadPreference());
}
Expand All @@ -1923,8 +1928,13 @@ public CommandResult getStats() {
* Checks whether this collection is capped
*
* @return true if this is a capped collection
* @mongodb.driver.manual /core/capped-collections/#check-if-a-collection-is-capped Capped Collections
* @mongodb.driver.manual core/capped-collections/#check-if-a-collection-is-capped Capped Collections
* @mongodb.driver.manual reference/operator/aggregation/collStats/ $collStats
* @deprecated If you are using server release 3.4 or newer, use the {@code $collStats} aggregation pipeline stage via
* {@link #aggregate(List, AggregationOptions)} instead, and inspect the {@code storageStats.capped} field.
* This method uses the {@code collStats} command, which is deprecated since server release 6.2.
*/
@Deprecated
public boolean isCapped() {
CommandResult commandResult = getStats();
Object cappedField = commandResult.get("capped");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ import org.bson.UuidRepresentation
import org.bson.codecs.BsonDocumentCodec
import org.bson.codecs.BsonValueCodec
import org.bson.codecs.UuidCodec
import spock.lang.IgnoreIf
import spock.lang.Specification

import java.util.concurrent.TimeUnit

import static Fixture.getMongoClient
import static com.mongodb.ClusterFixture.serverVersionAtLeast
import static com.mongodb.CustomMatchers.isTheSameAs
import static com.mongodb.LegacyMixedBulkWriteOperation.createBulkWriteOperationForDelete
import static com.mongodb.LegacyMixedBulkWriteOperation.createBulkWriteOperationForUpdate
Expand Down Expand Up @@ -260,6 +262,7 @@ class DBCollectionSpecification extends Specification {
thrown(IllegalArgumentException)
}

@IgnoreIf({ serverVersionAtLeast(6, 2) })
def 'getStats should execute the expected command with the collection default read preference'() {
given:
def executor = new TestOperationExecutor([new BsonDocument('ok', new BsonInt32(1))])
Expand Down
29 changes: 26 additions & 3 deletions driver-legacy/src/test/functional/com/mongodb/DBTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@
import static com.mongodb.ClusterFixture.isDiscoverableReplicaSet;
import static com.mongodb.ClusterFixture.isSharded;
import static com.mongodb.ClusterFixture.serverVersionAtLeast;
import static com.mongodb.ClusterFixture.serverVersionLessThan;
import static com.mongodb.DBObjectMatchers.hasFields;
import static com.mongodb.DBObjectMatchers.hasSubdocument;
import static com.mongodb.Fixture.getDefaultDatabaseName;
import static com.mongodb.Fixture.getMongoClient;
import static com.mongodb.ReadPreference.secondary;
import static com.mongodb.client.Fixture.getMongoClientSettingsBuilder;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.hasItems;
Expand Down Expand Up @@ -124,7 +126,7 @@ public void shouldCreateCappedCollection() {
collection.drop();
database.createCollection(collectionName, new BasicDBObject("capped", true)
.append("size", 242880));
assertTrue(database.getCollection(collectionName).isCapped());
assertTrue(isCapped(database.getCollection(collectionName)));
}

@Test
Expand All @@ -134,7 +136,7 @@ public void shouldCreateCappedCollectionWithMaxNumberOfDocuments() {
.append("size", 242880)
.append("max", 10));

assertThat(cappedCollectionWithMax.getStats(), hasSubdocument(new BasicDBObject("capped", true).append("max", 10)));
assertThat(storageStats(cappedCollectionWithMax), hasSubdocument(new BasicDBObject("capped", true).append("max", 10)));

for (int i = 0; i < 11; i++) {
cappedCollectionWithMax.insert(new BasicDBObject("x", i));
Expand All @@ -148,7 +150,7 @@ public void shouldCreateUncappedCollection() {
BasicDBObject creationOptions = new BasicDBObject("capped", false);
database.createCollection(collectionName, creationOptions);

assertFalse(database.getCollection(collectionName).isCapped());
assertFalse(isCapped(database.getCollection(collectionName)));
}

@Test(expected = MongoCommandException.class)
Expand Down Expand Up @@ -347,4 +349,25 @@ BsonDocument getCollectionInfo(final String collectionName) {
return new ListCollectionsOperation<>(getDefaultDatabaseName(), new BsonDocumentCodec())
.filter(new BsonDocument("name", new BsonString(collectionName))).execute(getBinding()).next().get(0);
}

private boolean isCapped(final DBCollection collection) {
if (serverVersionLessThan(6, 2)) {
return collection.isCapped();
} else {
Object capped = storageStats(collection).get("capped");
return Boolean.TRUE.equals(capped) || Integer.valueOf(1).equals(capped);
}
}

private DBObject storageStats(final DBCollection collection) {
if (serverVersionLessThan(6, 2)) {
return collection.getStats();
} else {
try (Cursor cursor = collection.aggregate(singletonList(
new BasicDBObject("$collStats", new BasicDBObject("storageStats", new BasicDBObject()))),
AggregationOptions.builder().build())) {
return (DBObject) cursor.next().get("storageStats");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ import org.bson.BsonDouble
import spock.lang.Specification

import static Fixture.getMongoClient
import static com.mongodb.ClusterFixture.serverVersionLessThan
import static com.mongodb.CustomMatchers.isTheSameAs
import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry
import static org.junit.Assume.assumeTrue
import static spock.util.matcher.HamcrestSupport.expect

class DBSpecification extends Specification {
Expand Down Expand Up @@ -202,6 +204,9 @@ class DBSpecification extends Specification {
}

def 'should use provided read preference for obedient commands'() {
if (cmd.get('collStats') != null) {
assumeTrue(serverVersionLessThan(6, 2))
}
given:
def mongo = Stub(MongoClient)
mongo.mongoClientOptions >> MongoClientOptions.builder().build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -721,13 +721,6 @@ public void testRunCommand() {
// Start runCommand Example 1
database.runCommand(new Document("buildInfo", 1));
// End runCommand Example 1

database.getCollection("restaurants").drop();
database.createCollection("restaurants");

// Start runCommand Example 2
database.runCommand(new Document("collStats", "restaurants"));
// End runCommand Example 2
}

@Test
Expand Down