Skip to content

Commit 655d85b

Browse files
authored
Merge branch 'master' into DOCSP-31343
2 parents 12bbc16 + ad30806 commit 655d85b

File tree

130 files changed

+5258
-365
lines changed

Some content is hidden

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

130 files changed

+5258
-365
lines changed

build.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# ensures that we always use the latest version of the script
2+
if [ -f build-site.sh ]; then
3+
rm build-site.sh
4+
fi
5+
6+
7+
curl https://raw.githubusercontent.com/mongodb/docs-worker-pool/netlify-poc/scripts/build-site.sh -o build-site.sh
8+
sh build-site.sh

config/redirects

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define: prefix docs/drivers/kotlin/coroutine
22
define: base https://www.mongodb.com/${prefix}
3-
define: versions v4.10 v4.11 master
3+
define: versions v4.10 v4.11 v5.0 v5.1 master
44

55
raw: ${prefix}/ -> ${base}/current/
66

examples/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ repositories {
1818
dependencies {
1919
implementation("org.mongodb:mongodb-driver-kotlin-coroutine:$kotlin_mongodb_version")
2020
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
21-
testImplementation(kotlin("test"))
21+
testImplementation("org.jetbrains.kotlin:kotlin-test:1.8.10")
2222
implementation("org.slf4j:slf4j-api:2.0.5")
2323
implementation("ch.qos.logback:logback-classic:1.4.7")
2424
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
@@ -28,7 +28,8 @@ dependencies {
2828
implementation("com.github.luben:zstd-jni:1.5.5-4")
2929
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1")
3030
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
31-
implementation("org.mongodb:bson-kotlinx:4.10.0-alpha1")
31+
implementation("org.mongodb:bson-kotlinx:$kotlin_mongodb_version")
32+
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
3233
}
3334

3435
tasks.test {

examples/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
kotlin.code.style=official
2-
kotlin_mongodb_version=4.10.0
2+
kotlin_mongodb_version=5.1.4

examples/src/test/kotlin/AggregatesBuilderTest.kt

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import com.mongodb.client.model.geojson.Position
2828
import com.mongodb.client.model.search.SearchOperator
2929
import com.mongodb.client.model.search.SearchOptions
3030
import com.mongodb.client.model.search.SearchPath
31+
import com.mongodb.client.model.search.VectorSearchOptions.vectorSearchOptions
3132
import com.mongodb.kotlin.client.coroutine.MongoClient
3233
import config.getConfig
3334
import kotlinx.coroutines.flow.firstOrNull
@@ -80,6 +81,15 @@ class AggregatesBuilderTest {
8081
)
8182
// :snippet-end:
8283

84+
// :snippet-start: vector-search-data-class
85+
data class MovieAlt(
86+
val title: String,
87+
val year: Int,
88+
val plot: String,
89+
val plotEmbedding: List<Double>
90+
)
91+
// :snippet-end:
92+
8393
companion object {
8494
val config = getConfig()
8595
private val client = MongoClient.create(config.connectionUri)
@@ -674,7 +684,15 @@ class AggregatesBuilderTest {
674684
// :snippet-end:
675685
Aggregates.sort(Sorts.descending(Results::count.name, "_id"))))
676686
val results = resultsFlow.toList()
677-
val actual = listOf(Results("Drama", 8), Results("Crime", 3), Results("Action", 2), Results("Thriller", 1), Results("Sci-Fi", 1), Results("Romance", 1), Results("Mystery", 1),)
687+
val actual = listOf(
688+
Results("Drama", 8),
689+
Results("Crime", 3),
690+
Results("Action", 2),
691+
Results("Thriller", 1),
692+
Results("Sci-Fi", 1),
693+
Results("Romance", 1),
694+
Results("Mystery", 1)
695+
)
678696
assertEquals(results, actual)
679697
}
680698

@@ -951,4 +969,27 @@ class AggregatesBuilderTest {
951969
assertEquals(1, resultsFlow.toList().size)
952970
assertEquals(1, results.first().get("count", Document::class.java).get("lowerBound", java.lang.Long::class.java)?.toInt())
953971
}
972+
973+
/* NOTE: Test is not run by default. Vector search requires the creation of a vector search index on the collection before running.
974+
*/
975+
@Ignore
976+
fun vectorSearchTest() = runBlocking {
977+
val resultsFlow = movieCollection.aggregate<Document>(
978+
listOf(
979+
// :snippet-start: vector-search
980+
Aggregates.vectorSearch(
981+
SearchPath.fieldPath(MovieAlt::plotEmbedding.name),
982+
listOf(-0.0072121937, -0.030757688, -0.012945653),
983+
"mflix_movies_embedding_index",
984+
2.toLong(),
985+
1.toLong(),
986+
vectorSearchOptions().filter(Filters.gte(MovieAlt::year.name, 2016))
987+
)
988+
// :snippet-end:
989+
)
990+
)
991+
val results = resultsFlow.toList()
992+
assertEquals(1, resultsFlow.toList().size)
993+
assertEquals(1, results.first().get("count", Document::class.java).get("lowerBound", java.lang.Long::class.java)?.toInt())
994+
}
954995
}

examples/src/test/kotlin/AuthTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ internal class AuthTest {
4747
fun defaultConnectionStringTest() = runBlocking {
4848
// :replace-start: {
4949
// "terms": {
50-
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<username>:<password>@<hostname>:<port>/?authSource=<authenticationDb>\""
50+
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>\""
5151
// }
5252
// }
5353
// :snippet-start: default-cred-string
@@ -70,7 +70,7 @@ internal class AuthTest {
7070
fun scramSha256ConnectionStringTest() = runBlocking {
7171
// :replace-start: {
7272
// "terms": {
73-
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<username>:<password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=SCRAM-SHA-256\""
73+
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=SCRAM-SHA-256\""
7474
// }
7575
// }
7676
// :snippet-start: scram-sha-256-string
@@ -93,7 +93,7 @@ internal class AuthTest {
9393
fun scramSha1ConnectionStringTest() = runBlocking {
9494
// :replace-start: {
9595
// "terms": {
96-
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<username>:<password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=SCRAM-SHA-1\""
96+
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=SCRAM-SHA-1\""
9797
// }
9898
// }
9999
// :snippet-start: scram-sha-1-string
@@ -116,7 +116,7 @@ internal class AuthTest {
116116
fun x509ConnectionStringTest() = runBlocking {
117117
// :replace-start: {
118118
// "terms": {
119-
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<username>:<password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=MONGODB-X509&tls=true\""
119+
// "CONNECTION_URI_PLACEHOLDER": "\"mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=<authenticationDb>&authMechanism=MONGODB-X509&tls=true\""
120120
// }
121121
// }
122122
// :snippet-start: x-509-string
@@ -137,8 +137,8 @@ internal class AuthTest {
137137

138138
// :replace-start: {
139139
// "terms": {
140-
// "USERNAME": "\"<username>\"",
141-
// "PASSWORD": "\"<password>\"",
140+
// "USERNAME": "\"<db_username>\"",
141+
// "PASSWORD": "\"<db_password>\"",
142142
// "AUTH_DB": "\"<authenticationDb>\"",
143143
// "HOSTNAME": "\"<hostname>\"",
144144
// "PORT": "\"<port>\""

examples/src/test/kotlin/ChangeStreamsTest.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import config.getConfig
1313
import kotlinx.coroutines.delay
1414
import kotlinx.coroutines.launch
1515
import kotlinx.coroutines.runBlocking
16+
import org.bson.BsonDocument
1617
import org.bson.Document
1718
import org.junit.jupiter.api.AfterAll
1819
import org.junit.jupiter.api.AfterEach
@@ -136,6 +137,37 @@ internal class ChangeStreamsTest {
136137

137138
}
138139

140+
// Ignore annotation added because this test requires a MongoDB 7.0 deployment
141+
@Ignore
142+
fun splitLargeChangeStreamTest() = runBlocking {
143+
val changeEvents = mutableListOf<ChangeStreamDocument<Document>>()
144+
// :snippet-start: split-large-change-stream
145+
val pipeline = listOf(BsonDocument().append("\$changeStreamSplitLargeEvent", BsonDocument()))
146+
147+
val job = launch {
148+
val changeStream = collection.watch(pipeline)
149+
changeStream.collect {
150+
println("Received a change event: $it")
151+
changeEvents.add(it) // :remove:
152+
}
153+
}
154+
// :snippet-end:
155+
156+
// Perform MongoDB operations that trigger change events...
157+
delay(1)
158+
val testData = Document("city", "Rio de Janeiro")
159+
collection.insertOne(testData)
160+
161+
// Wait for change events
162+
delay(1000)
163+
164+
// Cancel the change stream when you're done listening for events.
165+
job.cancel()
166+
167+
// Change stream only captures the insert event, not the delete event.
168+
assertEquals(1, changeEvents.size)
169+
}
170+
139171
// NOTE: Test is being ignored because it will not work with a shared M0 cluster.
140172
// Must have a local cluster with a replica set or >=M10 on Atlas to successfully run.
141173
@Ignore

examples/src/test/kotlin/CodecTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ internal class CodecTest {
6666

6767
init {
6868
powerStatusCodec = registry[PowerStatus::class.java]
69-
integerCodec = registry.get(Int::class.java)
69+
integerCodec = IntegerCodec()
7070
}
7171

7272
override fun encode(writer: BsonWriter, value: Monolight, encoderContext: EncoderContext) {

examples/src/test/kotlin/EnterpriseAuthTest.kt

Lines changed: 94 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ import com.mongodb.ConnectionString
33
import com.mongodb.KerberosSubjectProvider
44
import com.mongodb.MongoClientSettings
55
import com.mongodb.MongoCredential
6+
import com.mongodb.MongoCredential.OidcCallbackResult
67
import com.mongodb.ServerAddress
78
import com.mongodb.kotlin.client.coroutine.MongoClient
89
import kotlinx.coroutines.runBlocking
10+
import java.nio.file.Files
11+
import java.nio.file.Paths
12+
import javax.naming.Context
913
import javax.security.auth.Subject
1014
import javax.security.auth.login.LoginContext
1115
import kotlin.test.Ignore
16+
1217
// :replace-start: {
1318
// "terms": {
1419
// "PORT": "<port>",
@@ -32,7 +37,7 @@ internal class EnterpriseAuthTest {
3237

3338
fun createGSSAPICred() = runBlocking {
3439
// :snippet-start: auth-creds-gssapi
35-
val credential = MongoCredential.createGSSAPICredential("<username>")
40+
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
3641

3742
val settings = MongoClientSettings.builder()
3843
.applyToClusterSettings { builder ->
@@ -47,7 +52,7 @@ internal class EnterpriseAuthTest {
4752

4853
fun serviceNameKey() = runBlocking {
4954
// :snippet-start: service-name-key
50-
val credential = MongoCredential.createGSSAPICredential("<username>")
55+
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
5156
.withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, "myService")
5257
// :snippet-end:
5358
}
@@ -58,7 +63,7 @@ internal class EnterpriseAuthTest {
5863
loginContext.login()
5964
val subject: Subject = loginContext.subject
6065

61-
val credential = MongoCredential.createGSSAPICredential("<username>")
66+
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
6267
.withMechanismProperty(MongoCredential.JAVA_SUBJECT_KEY, subject)
6368
// :snippet-end:
6469
}
@@ -70,7 +75,7 @@ internal class EnterpriseAuthTest {
7075
val myLoginContext = "myContext"
7176
/* Login context defaults to "com.sun.security.jgss.krb5.initiate"
7277
if unspecified in KerberosSubjectProvider */
73-
val credential = MongoCredential.createGSSAPICredential("<username>")
78+
val credential = MongoCredential.createGSSAPICredential("<Kerberos principal>")
7479
.withMechanismProperty(
7580
MongoCredential.JAVA_SUBJECT_PROVIDER_KEY,
7681
KerberosSubjectProvider(myLoginContext)
@@ -80,7 +85,7 @@ internal class EnterpriseAuthTest {
8085

8186
fun ldapCredential() = runBlocking {
8287
// :snippet-start: ldap-mongo-credential
83-
val credential = MongoCredential.createPlainCredential("<username>", "$external", "<password>".toCharArray())
88+
val credential = MongoCredential.createPlainCredential("<LDAP username>", "$external", "<password>".toCharArray())
8489

8590
val settings = MongoClientSettings.builder()
8691
.applyToClusterSettings { builder ->
@@ -95,24 +100,105 @@ internal class EnterpriseAuthTest {
95100

96101
fun gssapiConnectionString() = runBlocking {
97102
// :snippet-start: gssapi-connection-string
98-
val connectionString = ConnectionString("<username>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI")
103+
val connectionString = ConnectionString("<Kerberos principal>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI")
99104
val mongoClient = MongoClient.create(connectionString)
100105
// :snippet-end:
101106
}
102107

103108
fun gssapiPropertiesConnectionString() = runBlocking {
104109
// :snippet-start: gssapi-properties-connection-string
105-
val connectionString = ConnectionString("<username>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:myService")
110+
val connectionString = ConnectionString("<Kerberos principal>@<hostname>:<port>/?authSource=$external&authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:myService")
106111
val mongoClient = MongoClient.create(connectionString)
107112
// :snippet-end:
108113
}
109114

110115
fun ldapConnectionString() = runBlocking {
111116
// :snippet-start: ldap-connection-string
112-
val connectionString = ConnectionString("<username>:<password>@<hostname>:<port>/?authSource=$external&authMechanism=PLAIN")
117+
val connectionString = ConnectionString("<LDAP username>:<password>@<hostname>:<port>/?authSource=$external&authMechanism=PLAIN")
118+
val mongoClient = MongoClient.create(connectionString)
119+
// :snippet-end:
120+
}
121+
122+
fun oidcAzureConnectionString() = runBlocking {
123+
// :snippet-start: oidc-azure-connection-string
124+
val connectionString = ConnectionString(
125+
"mongodb://<OIDC principal>@<hostname>:<port>/?" +
126+
"?authMechanism=MONGODB-OIDC" +
127+
"&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>")
128+
val mongoClient = MongoClient.create(connectionString)
129+
// :snippet-end:
130+
}
131+
132+
fun oidcAzureCredential() = runBlocking {
133+
// :snippet-start: oidc-azure-credential
134+
val credential = MongoCredential.createOidcCredential("<OIDC principal>")
135+
.withMechanismProperty("ENVIRONMENT", "azure")
136+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
137+
138+
val mongoClient = MongoClient.create(
139+
MongoClientSettings.builder()
140+
.applyToClusterSettings { builder ->
141+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
142+
}
143+
.credential(credential)
144+
.build())
145+
// :snippet-end:
146+
}
147+
148+
fun oidcGCPConnectionString() = runBlocking {
149+
// :snippet-start: oidc-gcp-connection-string
150+
val connectionString = ConnectionString(
151+
"mongodb://<OIDC principal>@<hostname>:<port>/?" +
152+
"authMechanism=MONGODB-OIDC" +
153+
"&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>")
113154
val mongoClient = MongoClient.create(connectionString)
114155
// :snippet-end:
115156
}
157+
158+
fun oidcGCPCredential() = runBlocking {
159+
// :snippet-start: oidc-gcp-credential
160+
val credential = MongoCredential.createOidcCredential("<OIDC principal>")
161+
.withMechanismProperty("ENVIRONMENT", "gcp")
162+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
163+
164+
val mongoClient = MongoClient.create(
165+
MongoClientSettings.builder()
166+
.applyToClusterSettings { builder ->
167+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
168+
}
169+
.credential(credential)
170+
.build())
171+
// :snippet-end:
172+
}
173+
174+
fun oidcCallback() = runBlocking {
175+
// :snippet-start: oidc-callback
176+
val credential = MongoCredential.createOidcCredential(null)
177+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
178+
val accessToken = "..."
179+
OidcCallbackResult(accessToken)
180+
}
181+
// :snippet-end:
182+
}
183+
184+
fun oidcCallbackFile() = runBlocking {
185+
// :snippet-start: oidc-callback-file
186+
val credential = MongoCredential.createOidcCredential(null)
187+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
188+
val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat")))
189+
OidcCallbackResult(accessToken)
190+
}
191+
192+
val mongoClient = MongoClient.create(
193+
MongoClientSettings.builder()
194+
.applyToClusterSettings { builder ->
195+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
196+
}
197+
.credential(credential)
198+
.build()
199+
)
200+
// :snippet-end:
201+
}
116202
}
117203
// :replace-end:
118204

examples/src/test/kotlin/InsertTest.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
import com.mongodb.MongoBulkWriteException
42
import com.mongodb.kotlin.client.coroutine.MongoClient
53
import config.getConfig

0 commit comments

Comments
 (0)