@ -15,12 +15,15 @@
* /
* /
package org.springframework.data.mongodb.test.util ;
package org.springframework.data.mongodb.test.util ;
import org.jspecify.annotations.Nullable ;
import org.springframework.util.StringUtils ;
import reactor.core.publisher.Mono ;
import reactor.core.publisher.Mono ;
import reactor.test.StepVerifier ;
import reactor.test.StepVerifier ;
import reactor.util.retry.Retry ;
import reactor.util.retry.Retry ;
import java.time.Duration ;
import java.time.Duration ;
import java.util.List ;
import java.util.List ;
import java.util.concurrent.TimeUnit ;
import org.bson.Document ;
import org.bson.Document ;
import org.springframework.core.env.Environment ;
import org.springframework.core.env.Environment ;
@ -30,6 +33,7 @@ import org.springframework.data.util.Version;
import org.springframework.util.ObjectUtils ;
import org.springframework.util.ObjectUtils ;
import com.mongodb.ConnectionString ;
import com.mongodb.ConnectionString ;
import com.mongodb.MongoClientSettings ;
import com.mongodb.ReadPreference ;
import com.mongodb.ReadPreference ;
import com.mongodb.WriteConcern ;
import com.mongodb.WriteConcern ;
import com.mongodb.client.MongoClient ;
import com.mongodb.client.MongoClient ;
@ -68,6 +72,10 @@ public class MongoTestUtils {
}
}
public static MongoClient client ( ConnectionString connectionString ) {
public static MongoClient client ( ConnectionString connectionString ) {
MongoClientSettings settings = MongoClientSettings . builder ( ) . applyConnectionString ( connectionString )
. applyToSocketSettings ( builder - > {
builder . connectTimeout ( 120 , TimeUnit . SECONDS ) ;
} ) . build ( ) ;
return com . mongodb . client . MongoClients . create ( connectionString , SpringDataMongoDB . driverInformation ( ) ) ;
return com . mongodb . client . MongoClients . create ( connectionString , SpringDataMongoDB . driverInformation ( ) ) ;
}
}
@ -176,11 +184,10 @@ public class MongoTestUtils {
* @param collectionName must not be { @literal null } .
* @param collectionName must not be { @literal null } .
* @param client must not be { @literal null } .
* @param client must not be { @literal null } .
* /
* /
public static void dropCollectionNow ( String dbName , String collectionName ,
public static void dropCollectionNow ( String dbName , String collectionName , com . mongodb . client . MongoClient client ) {
com . mongodb . client . MongoClient client ) {
com . mongodb . client . MongoDatabase database = client . getDatabase ( dbName )
com . mongodb . client . MongoDatabase database = client . getDatabase ( dbName ) . withWriteConcern ( WriteConcern . MAJORITY )
. withWriteConcern ( WriteConcern . MAJORITY ) . with ReadPreference ( ReadPreference . primary ( ) ) ;
. withReadPreference ( ReadPreference . primary ( ) ) ;
database . getCollection ( collectionName ) . drop ( ) ;
database . getCollection ( collectionName ) . drop ( ) ;
}
}
@ -205,11 +212,10 @@ public class MongoTestUtils {
. verifyComplete ( ) ;
. verifyComplete ( ) ;
}
}
public static void flushCollection ( String dbName , String collectionName ,
public static void flushCollection ( String dbName , String collectionName , com . mongodb . client . MongoClient client ) {
com . mongodb . client . MongoClient client ) {
com . mongodb . client . MongoDatabase database = client . getDatabase ( dbName )
com . mongodb . client . MongoDatabase database = client . getDatabase ( dbName ) . withWriteConcern ( WriteConcern . MAJORITY )
. withWriteConcern ( WriteConcern . MAJORITY ) . with ReadPreference ( ReadPreference . primary ( ) ) ;
. withReadPreference ( ReadPreference . primary ( ) ) ;
database . getCollection ( collectionName ) . deleteMany ( new Document ( ) ) ;
database . getCollection ( collectionName ) . deleteMany ( new Document ( ) ) ;
}
}
@ -267,10 +273,15 @@ public class MongoTestUtils {
@SuppressWarnings ( "unchecked" )
@SuppressWarnings ( "unchecked" )
public static boolean isVectorSearchEnabled ( ) {
public static boolean isVectorSearchEnabled ( ) {
try ( MongoClient client = MongoTestUtils . client ( ) ) {
try ( MongoClient client = MongoTestUtils . client ( ) ) {
return isVectorSearchEnabled ( client ) ;
}
}
public static boolean isVectorSearchEnabled ( MongoClient client ) {
try {
return client . getDatabase ( "admin" ) . runCommand ( new Document ( "getCmdLineOpts" , "1" ) ) . get ( "argv" , List . class )
return client . getDatabase ( "admin" ) . runCommand ( new Document ( "getCmdLineOpts" , "1" ) ) . get ( "argv" , List . class )
. stream ( ) . anyMatch ( it - > {
. stream ( ) . anyMatch ( it - > {
if ( it instanceof String cfgString ) {
if ( it instanceof String cfgString ) {
return cfgString . startsWith ( "searchIndexManagementHostAndPort" ) ;
return cfgString . startsWith ( "searchIndexManagementHostAndPort" ) ;
}
}
return false ;
return false ;
@ -280,6 +291,18 @@ public class MongoTestUtils {
}
}
}
}
public static boolean isSearchIndexReady ( MongoClient client , @Nullable String database , String collectionName ) {
try {
MongoCollection < Document > collection = client . getDatabase ( StringUtils . hasText ( database ) ? database : "test" ) . getCollection ( collectionName ) ;
collection . aggregate ( List . of ( new Document ( "$listSearchIndexes" , new Document ( ) ) ) ) ;
} catch ( Exception e ) {
return false ;
}
return true ;
}
public static Duration getTimeout ( ) {
public static Duration getTimeout ( ) {
return ObjectUtils . nullSafeEquals ( "jenkins" , ENV . getProperty ( "user.name" ) ) ? Duration . ofMillis ( 100 )
return ObjectUtils . nullSafeEquals ( "jenkins" , ENV . getProperty ( "user.name" ) ) ? Duration . ofMillis ( 100 )
@ -297,10 +320,11 @@ public class MongoTestUtils {
public static CollectionInfo readCollectionInfo ( MongoDatabase db , String collectionName ) {
public static CollectionInfo readCollectionInfo ( MongoDatabase db , String collectionName ) {
List < Document > list = db . runCommand ( new Document ( ) . append ( "listCollections" , 1 ) . append ( "filter" , new Document ( "name" , collectionName ) ) )
List < Document > list = db
. runCommand ( new Document ( ) . append ( "listCollections" , 1 ) . append ( "filter" , new Document ( "name" , collectionName ) ) )
. get ( "cursor" , Document . class ) . get ( "firstBatch" , List . class ) ;
. get ( "cursor" , Document . class ) . get ( "firstBatch" , List . class ) ;
if ( list . isEmpty ( ) ) {
if ( list . isEmpty ( ) ) {
throw new IllegalStateException ( String . format ( "Collection %s not found." , collectionName ) ) ;
throw new IllegalStateException ( String . format ( "Collection %s not found." , collectionName ) ) ;
}
}
return CollectionInfo . from ( list . get ( 0 ) ) ;
return CollectionInfo . from ( list . get ( 0 ) ) ;