Skip to content

Commit

Permalink
Updates to MongoSettings to better handle parsing the connection url,…
Browse files Browse the repository at this point in the history
… and allowing more options to be passed to the embeddedMongo, such as the mongo version, port, and database name.
  • Loading branch information
bjsvedin committed Sep 25, 2023
1 parent 2a7c95f commit ed78ba3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.lightningkite.lightningdb

import com.github.jershell.kbson.*
import com.lightningkite.lightningserver.core.Disconnectable
import com.lightningkite.lightningserver.db.DatabaseSettings
import com.lightningkite.lightningserver.serialization.Serialization
Expand All @@ -9,23 +8,13 @@ import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.kotlin.client.coroutine.MongoClient
import com.mongodb.kotlin.client.coroutine.MongoCollection
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.overwriteWith
import kotlinx.serialization.serializer
import org.bson.BsonDocument
import org.bson.BsonTimestamp
import org.bson.UuidRepresentation
import org.bson.types.Binary
import org.bson.types.ObjectId
import java.io.File
import java.math.BigDecimal
import java.time.*
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit
import kotlin.reflect.KClass
import kotlin.reflect.KType

class MongoDatabase(val databaseName: String, private val makeClient: () -> MongoClient) : Database, Disconnectable {
Expand Down Expand Up @@ -53,46 +42,78 @@ class MongoDatabase(val databaseName: String, private val makeClient: () -> Mong
companion object {
init {
DatabaseSettings.register("mongodb") {
val databaseName: String =
it.url.substringAfter("://").substringAfter('@').substringAfter('/', "").substringBefore('?')
MongoDatabase(databaseName = databaseName) {
MongoClient.create(MongoClientSettings.builder()
.applyConnectionString(ConnectionString(it.url))
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyToConnectionPoolSettings {
if (Settings.isServerless) {
it.maxSize(4)
it.maxConnectionIdleTime(15, TimeUnit.SECONDS)
it.maxConnectionLifeTime(1L, TimeUnit.MINUTES)
}
Regex("""mongodb://.*/(?<databaseName>[^?]+)(?:\?.*)?""")
.matchEntire(it.url)
?.let { match ->
MongoDatabase(databaseName = match.groups["databaseName"]!!.value) {
MongoClient.create(MongoClientSettings.builder()
.applyConnectionString(ConnectionString(it.url))
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyToConnectionPoolSettings {
if (Settings.isServerless) {
it.maxSize(4)
it.maxConnectionIdleTime(15, TimeUnit.SECONDS)
it.maxConnectionLifeTime(1L, TimeUnit.MINUTES)
}
}
.build()
)
}
.build()
)
}
}
?: throw IllegalStateException("Invalid mongodb URL. The URL should match the pattern: mongodb://[credentials and host information]/[databaseName]?[params]")
}
DatabaseSettings.register("mongodb+srv") {
val databaseName: String =
it.url.substringAfter("://").substringAfter('@').substringAfter('/', "").substringBefore('?')
MongoDatabase(databaseName = databaseName) {
MongoClient.create(MongoClientSettings.builder()
.applyConnectionString(ConnectionString(it.url))
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyToConnectionPoolSettings {
if (Settings.isServerless) {
it.maxSize(4)
it.maxConnectionIdleTime(15, TimeUnit.SECONDS)
it.maxConnectionLifeTime(1L, TimeUnit.MINUTES)
}
Regex("""mongodb\+srv://.*/(?<databaseName>[^?]+)(?:\?.*)?""")
.matchEntire(it.url)
?.let { match ->
MongoDatabase(databaseName = match.groups["databaseName"]!!.value) {
MongoClient.create(MongoClientSettings.builder()
.applyConnectionString(ConnectionString(it.url))
.uuidRepresentation(UuidRepresentation.STANDARD)
.applyToConnectionPoolSettings {
if (Settings.isServerless) {
it.maxSize(4)
it.maxConnectionIdleTime(15, TimeUnit.SECONDS)
it.maxConnectionLifeTime(1L, TimeUnit.MINUTES)
}
}
.build()
)
}
.build()
)
}
}
?: throw IllegalStateException("Invalid mongodb URL. The URL should match the pattern: mongodb+srv://[credentials and host information]/[databaseName]?[params]")
}
DatabaseSettings.register("mongodb-test") {
MongoDatabase(databaseName = "default") { testMongo() }
Regex("""mongodb-test://(?:\?(?<params>.*))?""")
.matchEntire(it.url)
?.let { match ->
val params: Map<String, List<String>>? = match.groups["params"]?.value?.let { params ->
DatabaseSettings.parseParameterString(params)
}
MongoDatabase(databaseName = "default") {
testMongo(version = params?.get("mongoVersion")?.firstOrNull())
}
}
?: throw IllegalStateException("Invalid mongodb-test URL. The URL should match the pattern: mongodb-test://?[params]\nAvailable params are: mongoVersion")
}
DatabaseSettings.register("mongodb-file") {
MongoDatabase(databaseName = "default") { embeddedMongo(File(it.url.removePrefix("mongodb-file://"))) }
Regex("""mongodb-file://(?<folder>[^?]+)(?:\?(?<params>.*))?""")
.matchEntire(it.url)
?.let { match ->
val folder = match.groups["folder"]!!.value
val params: Map<String, List<String>>? = match.groups["params"]?.value?.let { params ->
DatabaseSettings.parseParameterString(params)
}
MongoDatabase(databaseName = params?.get("databaseName")?.firstOrNull() ?: "default") {
embeddedMongo(
replFile = File(folder),
port = params?.get("port")?.firstOrNull()?.toIntOrNull(),
version = params?.get("mongoVersion")?.firstOrNull()
)
}

}
?: throw IllegalStateException("Invalid mongodb-file URL. The URL should match the pattern: mongodb-file://[FolderPath]?[params]\nAvailable params are: mongoVersion, port, databaseName")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ import java.nio.file.Files

fun testMongo(
replFile: File = Files.createTempDirectory("embeddedMongo").toFile(),
port: Int? = null,
version: String? = null
): MongoClient = embeddedMongo(
true,
replFile,
port ?: Network.freeServerPort(Network.getLocalHost()),
version?.let { Version.Main.valueOf(it) } ?: Version.Main.V6_0
deleteAfter = true,
replFile = replFile,
port = Network.freeServerPort(Network.getLocalHost()),
version = version?.let { Version.Main.valueOf(it) } ?: Version.Main.V6_0
)

fun embeddedMongo(
Expand All @@ -33,10 +32,10 @@ fun embeddedMongo(
version: String? = null
): MongoClient =
embeddedMongo(
false,
replFile,
port ?: 54961,
version?.let { Version.Main.valueOf(it) } ?: Version.Main.V6_0
deleteAfter = false,
replFile = replFile,
port = port ?: 54961,
version = version?.let { Version.Main.valueOf(it) } ?: Version.Main.V6_0
)

private fun embeddedMongo(
Expand Down

0 comments on commit ed78ba3

Please sign in to comment.