diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 346d645fd..61ed1e3da 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -14,5 +14,5 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar diff --git a/adoptium-api-v3-persistence/pom.xml b/adoptium-api-v3-persistence/pom.xml index 9968b9275..776a3eabe 100644 --- a/adoptium-api-v3-persistence/pom.xml +++ b/adoptium-api-v3-persistence/pom.xml @@ -13,8 +13,12 @@ - org.litote.kmongo - kmongo-coroutine + org.mongodb + mongodb-driver-kotlin-coroutine + + + com.fasterxml.jackson.datatype + jackson-datatype-jakarta-jsonp net.adoptium.api @@ -41,6 +45,17 @@ jakarta.enterprise jakarta.enterprise.cdi-api + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/DownloadStatsInterface.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/DownloadStatsInterface.kt index 7dba12ad0..038f85ab7 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/DownloadStatsInterface.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/DownloadStatsInterface.kt @@ -119,8 +119,8 @@ class DownloadStatsInterface { return stats.groupBy { it.dateTime.toLocalDate() } .map { grouped -> StatEntry( - grouped.value.map { it.dateTime }.maxOrNull()!!, - grouped.value.map { it.count }.sum() + grouped.value.maxOf { it.dateTime }, + grouped.value.sumOf { it.count } ) } .sortedBy { it.dateTime } @@ -161,7 +161,7 @@ class DownloadStatsInterface { private fun calculateMonthlyDiff( stats: Collection ): List { - val toTwoChar = { value: Int -> if (value < 10) "0" + value else value.toString() } // Returns in MM format + val toTwoChar = { value: Int -> if (value < 10) "0$value" else value.toString() } // Returns in MM format return stats .windowed(2, 1, false) { @@ -244,16 +244,14 @@ class DownloadStatsInterface { return stats .groupBy { it.getId() } .map { grouped -> grouped.value.maxByOrNull { it.date } } - .map { it!!.getMetric() } - .sum() + .sumOf { it!!.getMetric() } } private fun formTotalDownloads(stats: List, jvmImpl: JvmImpl): Long { return stats .groupBy { it.getId() } .map { grouped -> grouped.value.maxByOrNull { it.date } } - .map { (it!!.jvmImplDownloads?.get(jvmImpl) ?: 0) } - .sum() + .sumOf { (it!!.jvmImplDownloads?.get(jvmImpl) ?: 0) } } suspend fun getTotalDownloadStats(): DownloadStats { @@ -261,21 +259,13 @@ class DownloadStatsInterface { val githubStats = getGithubStats() - val dockerPulls = dockerStats - .map { it.pulls } - .sum() + val dockerPulls = dockerStats.sumOf { it.pulls } - val githubDownloads = githubStats - .map { it.downloads } - .sum() + val githubDownloads = githubStats.sumOf { it.downloads } - val dockerBreakdown = dockerStats - .map { Pair(it.repo, it.pulls) } - .toMap() + val dockerBreakdown = dockerStats.associate { Pair(it.repo, it.pulls) } - val githubBreakdown = githubStats - .map { Pair(it.feature_version, it.downloads) } - .toMap() + val githubBreakdown = githubStats.associate { Pair(it.feature_version, it.downloads) } val totalStats = TotalStats(dockerPulls, githubDownloads, dockerPulls + githubDownloads) return DownloadStats(TimeSource.now(), totalStats, githubBreakdown, dockerBreakdown) diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/JsonMapper.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/JsonMapper.kt index a4a0db970..592d15052 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/JsonMapper.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/JsonMapper.kt @@ -3,11 +3,9 @@ package net.adoptium.api.v3 import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import com.fasterxml.jackson.module.kotlin.KotlinModule object JsonMapper { - val mapper: ObjectMapper = ObjectMapper() + val mapper: ObjectMapper = com.fasterxml.jackson.module.kotlin.jacksonObjectMapper() .setSerializationInclusion(JsonInclude.Include.NON_NULL) - .registerModule(KotlinModule.Builder().build()) .registerModule(JavaTimeModule()) } diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/APIDataStoreImpl.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/APIDataStoreImpl.kt index cd90c6069..f4b7763ca 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/APIDataStoreImpl.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/APIDataStoreImpl.kt @@ -24,7 +24,10 @@ open class APIDataStoreImpl : APIDataStore { private var updatedAt: UpdatedInfo private var binaryRepos: AdoptRepos private var releaseInfo: ReleaseInfo - open var schedule: ScheduledFuture<*>? + private var schedule: ScheduledFuture<*>? + + // required as injection objects to the final field + open fun getSchedule() = schedule companion object { @JvmStatic diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoApiPersistence.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoApiPersistence.kt index c97b21482..db5db6dab 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoApiPersistence.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoApiPersistence.kt @@ -1,10 +1,13 @@ package net.adoptium.api.v3.dataSources.persitence.mongo import com.mongodb.client.model.InsertManyOptions -import com.mongodb.client.model.UpdateOptions +import com.mongodb.client.model.ReplaceOptions +import com.mongodb.kotlin.client.coroutine.MongoCollection import jakarta.enterprise.context.ApplicationScoped -import jakarta.enterprise.inject.Model import jakarta.inject.Inject +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.toList import net.adoptium.api.v3.TimeSource import net.adoptium.api.v3.dataSources.models.AdoptRepos import net.adoptium.api.v3.dataSources.models.FeatureRelease @@ -24,19 +27,18 @@ import org.bson.BsonDateTime import org.bson.BsonDocument import org.bson.BsonString import org.bson.Document -import org.litote.kmongo.coroutine.CoroutineCollection import org.slf4j.LoggerFactory import java.time.ZonedDateTime @ApplicationScoped open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : MongoInterface(), ApiPersistence { - private val githubReleaseMetadataCollection: CoroutineCollection = createCollection(mongoClient.database, GH_RELEASE_METADATA) - private val releasesCollection: CoroutineCollection = createCollection(mongoClient.database, RELEASE_DB) - private val gitHubStatsCollection: CoroutineCollection = createCollection(mongoClient.database, GITHUB_STATS_DB) - private val dockerStatsCollection: CoroutineCollection = createCollection(mongoClient.database, DOCKER_STATS_DB) - private val releaseInfoCollection: CoroutineCollection = createCollection(mongoClient.database, RELEASE_INFO_DB) - private val updateTimeCollection: CoroutineCollection = createCollection(mongoClient.database, UPDATE_TIME_DB) - private val githubReleaseNotesCollection: CoroutineCollection = createCollection(mongoClient.database, GH_RELEASE_NOTES) + private val githubReleaseMetadataCollection: MongoCollection = createCollection(mongoClient.getDatabase(), GH_RELEASE_METADATA) + private val releasesCollection: MongoCollection = createCollection(mongoClient.getDatabase(), RELEASE_DB) + private val gitHubStatsCollection: MongoCollection = createCollection(mongoClient.getDatabase(), GITHUB_STATS_DB) + private val dockerStatsCollection: MongoCollection = createCollection(mongoClient.getDatabase(), DOCKER_STATS_DB) + private val releaseInfoCollection: MongoCollection = createCollection(mongoClient.getDatabase(), RELEASE_INFO_DB) + private val updateTimeCollection: MongoCollection = createCollection(mongoClient.getDatabase(), UPDATE_TIME_DB) + private val githubReleaseNotesCollection: MongoCollection = createCollection(mongoClient.getDatabase(), GH_RELEASE_NOTES) companion object { @JvmStatic @@ -119,7 +121,7 @@ open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : M val repoNames = dockerStatsCollection.distinct("repo").toList() return repoNames - .mapNotNull { + .map { dockerStatsCollection .find(Document("repo", it)) .sort(Document("date", -1)) @@ -137,31 +139,31 @@ open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : M override suspend fun setReleaseInfo(releaseInfo: ReleaseInfo) { releaseInfoCollection.deleteMany(releaseVersionDbEntryMatcher()) - releaseInfoCollection.updateOne( + releaseInfoCollection.replaceOne( releaseVersionDbEntryMatcher(), releaseInfo, - UpdateOptions().upsert(true) + ReplaceOptions().upsert(true) ) } // visible for testing open suspend fun updateUpdatedTime(dateTime: ZonedDateTime, checksum: String, hashCode: Int) { - updateTimeCollection.updateOne( + updateTimeCollection.replaceOne( Document(), UpdatedInfo(dateTime, checksum, hashCode), - UpdateOptions().upsert(true) + ReplaceOptions().upsert(true) ) updateTimeCollection.deleteMany(Document("time", BsonDocument("\$lt", BsonDateTime(dateTime.toInstant().toEpochMilli())))) } override suspend fun getUpdatedAt(): UpdatedInfo { - val info = updateTimeCollection.findOne() + val info = updateTimeCollection.find().firstOrNull() // if we have no existing time, make it 5 mins ago, should only happen on first time the db is used return info ?: UpdatedInfo(TimeSource.now().minusMinutes(5), "000", 0) } override suspend fun getReleaseInfo(): ReleaseInfo? { - return releaseInfoCollection.findOne(releaseVersionDbEntryMatcher()) + return releaseInfoCollection.find(releaseVersionDbEntryMatcher()).firstOrNull() } private fun releaseVersionDbEntryMatcher() = Document("tip_version", BsonDocument("\$exists", BsonBoolean(true))) @@ -181,20 +183,20 @@ open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : M private fun majorVersionMatcher(featureVersion: Int) = Document("version_data.major", featureVersion) override suspend fun getGhReleaseMetadata(gitHubId: GitHubId): GHReleaseMetadata? { - return githubReleaseMetadataCollection.findOne(matchGithubId(gitHubId)) + return githubReleaseMetadataCollection.find(matchGithubId(gitHubId)).firstOrNull() } override suspend fun setGhReleaseMetadata(ghReleaseMetadata: GHReleaseMetadata) { githubReleaseMetadataCollection - .updateOne( + .replaceOne( matchGithubId(ghReleaseMetadata.gitHubId), ghReleaseMetadata, - UpdateOptions().upsert(true) + ReplaceOptions().upsert(true) ) } override suspend fun hasReleaseNotesForGithubId(gitHubId: GitHubId): Boolean { - return githubReleaseNotesCollection.findOne(Document("id", gitHubId.id)) != null + return githubReleaseNotesCollection.find(Document("id", gitHubId.id)).firstOrNull() != null } override suspend fun putReleaseNote(releaseNotes: ReleaseNotes) { @@ -203,7 +205,7 @@ open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : M } override suspend fun getReleaseNotes(vendor: Vendor, releaseName: String): ReleaseNotes? { - return githubReleaseNotesCollection.findOne(Document( + return githubReleaseNotesCollection.find(Document( "\$and", BsonArray( listOf( @@ -213,6 +215,7 @@ open class MongoApiPersistence @Inject constructor(mongoClient: MongoClient) : M ) ) ) + .firstOrNull() } private fun matchGithubId(gitHubId: GitHubId) = Document("gitHubId.id", gitHubId.id) diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoClient.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoClient.kt index 17ed9d23c..1bab7aa97 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoClient.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoClient.kt @@ -2,17 +2,21 @@ package net.adoptium.api.v3.dataSources.persitence.mongo import com.mongodb.ConnectionString import com.mongodb.MongoClientSettings +import com.mongodb.kotlin.client.coroutine.MongoDatabase import jakarta.enterprise.context.ApplicationScoped -import org.litote.kmongo.coroutine.CoroutineClient -import org.litote.kmongo.coroutine.CoroutineDatabase -import org.litote.kmongo.coroutine.coroutine -import org.litote.kmongo.reactivestreams.KMongo +import net.adoptium.api.v3.dataSources.persitence.mongo.codecs.JacksonCodecProvider +import net.adoptium.api.v3.dataSources.persitence.mongo.codecs.ZonedDateTimeCodecProvider +import org.bson.codecs.configuration.CodecRegistries import org.slf4j.LoggerFactory + @ApplicationScoped open class MongoClient { - open val database: CoroutineDatabase - open val client: CoroutineClient + private val database: MongoDatabase + private val client: com.mongodb.kotlin.client.coroutine.MongoClient + + // required as injection objects to the final field + open fun getDatabase() = database companion object { @JvmStatic @@ -65,6 +69,12 @@ open class MongoClient { serverSelectionTimeoutMills = System.getenv("MONGODB_SERVER_SELECTION_TIMEOUT_MILLIS") ) var settingsBuilder = MongoClientSettings.builder() + .codecRegistry(CodecRegistries.fromProviders( + MongoClientSettings.getDefaultCodecRegistry(), + ZonedDateTimeCodecProvider(), + JacksonCodecProvider() + ) + ) .applyConnectionString(ConnectionString(connectionString)) val sslEnabled = System.getenv("MONGODB_SSL")?.toBoolean() if (sslEnabled == true) { @@ -72,7 +82,8 @@ open class MongoClient { settingsBuilder = settingsBuilder.applyToSslSettings { it.enabled(true).invalidHostNameAllowed(checkMongoHostName) } } - client = KMongo.createClient(settingsBuilder.build()).coroutine + client = com.mongodb.kotlin.client.coroutine.MongoClient.create(settingsBuilder.build()) database = client.getDatabase(dbName) } + } diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoInterface.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoInterface.kt index 4b1253101..9086ceaa2 100644 --- a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoInterface.kt +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/MongoInterface.kt @@ -1,18 +1,25 @@ package net.adoptium.api.v3.dataSources.persitence.mongo +import com.mongodb.MongoCommandException +import com.mongodb.kotlin.client.coroutine.MongoCollection +import com.mongodb.kotlin.client.coroutine.MongoDatabase import kotlinx.coroutines.runBlocking -import org.litote.kmongo.coroutine.CoroutineCollection -import org.litote.kmongo.coroutine.CoroutineDatabase abstract class MongoInterface { - inline fun createCollection(database: CoroutineDatabase, collectionName: String): CoroutineCollection { - return runBlocking { - if (!database.listCollectionNames().contains(collectionName)) { - // TODO add indexes + inline fun createCollection(database: MongoDatabase, collectionName: String): MongoCollection { + runBlocking { + try { database.createCollection(collectionName) + } catch (e: MongoCommandException) { + if (e.errorCode == 48) { + // collection already exists ... ignore + } else { + throw e + } } - return@runBlocking database.getCollection(collectionName) } + return database.getCollection(collectionName, T::class.java) + } } diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/JacksonCodecProvider.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/JacksonCodecProvider.kt new file mode 100644 index 000000000..93df8c708 --- /dev/null +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/JacksonCodecProvider.kt @@ -0,0 +1,65 @@ +package net.adoptium.api.v3.dataSources.persitence.mongo.codecs + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.DeserializationFeature +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule +import org.bson.BsonReader +import org.bson.BsonWriter +import org.bson.RawBsonDocument +import org.bson.codecs.Codec +import org.bson.codecs.DecoderContext +import org.bson.codecs.EncoderContext +import org.bson.codecs.configuration.CodecProvider +import org.bson.codecs.configuration.CodecRegistry +import java.io.IOException +import java.io.UncheckedIOException +import java.time.ZonedDateTime + +class JacksonCodecProvider : CodecProvider { + companion object { + private val objectMapper: ObjectMapper = com.fasterxml.jackson.module.kotlin.jacksonObjectMapper() + .setSerializationInclusion(JsonInclude.Include.NON_NULL) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .registerModule(JavaTimeModule()) + .registerModule(object : SimpleModule() { + init { + addDeserializer(ZonedDateTime::class.java, ZonedDateTimeDeserializer()) + } + }) + } + + override fun get(type: Class, registry: CodecRegistry): Codec? { + if (type == RawBsonDocument::class.java) { + return null + } + return JacksonCodec(objectMapper, registry, type) + } +} + +class JacksonCodec(private val objectMapper: ObjectMapper, private val registry: CodecRegistry, val type: Class) : Codec { + + private var rawBsonDocumentCodec: Codec = registry.get(RawBsonDocument::class.java) + + override fun encode(bsonWriter: BsonWriter?, value: T, encoderContext: EncoderContext?) { + val doc = RawBsonDocument.parse(objectMapper.writeValueAsString(value)) + + rawBsonDocumentCodec.encode(bsonWriter, doc, encoderContext) + } + + override fun getEncoderClass(): Class { + return type + } + + override fun decode(reader: BsonReader, decoderContext: DecoderContext): T { + try { + val codec = registry.get(RawBsonDocument::class.java) + val document: RawBsonDocument? = codec?.decode(reader, decoderContext) + val json = document?.toJson() + return objectMapper.readValue(json, type) + } catch (e: IOException) { + throw UncheckedIOException(e) + } + } +} diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeCodecProvider.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeCodecProvider.kt new file mode 100644 index 000000000..7528d8043 --- /dev/null +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeCodecProvider.kt @@ -0,0 +1,44 @@ +package net.adoptium.api.v3.dataSources.persitence.mongo.codecs + +import net.adoptium.api.v3.TimeSource +import org.bson.BsonReader +import org.bson.BsonWriter +import org.bson.codecs.Codec +import org.bson.codecs.DecoderContext +import org.bson.codecs.EncoderContext +import org.bson.codecs.configuration.CodecProvider +import org.bson.codecs.configuration.CodecRegistry +import java.time.Instant +import java.time.ZonedDateTime + +class ZonedDateTimeCodecProvider : CodecProvider { + override fun get(type: Class?, registry: CodecRegistry?): Codec? { + if (type == ZonedDateTime::class.java) { + return ZonedDateTimeCodec() as Codec + } + return null + } +} + +class ZonedDateTimeCodec : Codec { + override fun encode(writer: BsonWriter?, value: ZonedDateTime?, encoder: EncoderContext?) { + if (value == null) { + writer?.writeNull() + } else { + writer?.writeDateTime(value.withZoneSameInstant(TimeSource.ZONE).toInstant().toEpochMilli()) + } + } + + override fun getEncoderClass(): Class { + return ZonedDateTime::class.java + } + + override fun decode(reader: BsonReader?, decoderContext: DecoderContext?): ZonedDateTime? { + val date = reader?.readDateTime() + return if (date == null) { + null + } else { + ZonedDateTime.ofInstant(Instant.ofEpochMilli(date), TimeSource.ZONE) + } + } +} diff --git a/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeDeserializer.kt b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeDeserializer.kt new file mode 100644 index 000000000..0fe88b093 --- /dev/null +++ b/adoptium-api-v3-persistence/src/main/kotlin/net/adoptium/api/v3/dataSources/persitence/mongo/codecs/ZonedDateTimeDeserializer.kt @@ -0,0 +1,32 @@ +package net.adoptium.api.v3.dataSources.persitence.mongo.codecs + +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonDeserializer +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.node.LongNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.databind.node.TextNode +import net.adoptium.api.v3.TimeSource +import java.time.ZonedDateTime + +class ZonedDateTimeDeserializer : JsonDeserializer() { + override fun deserialize(jsonParser: JsonParser?, context: DeserializationContext?): ZonedDateTime { + when (val value = jsonParser?.readValueAsTree()) { + is ObjectNode -> { + return ZonedDateTime.parse(value.get("\$date").asText()) + } + + is TextNode -> { + return ZonedDateTime.parse(value.asText()) + } + + is LongNode -> { + return ZonedDateTime.ofInstant(java.time.Instant.ofEpochMilli(value.asLong()), TimeSource.ZONE) + } + } + + throw IllegalArgumentException("Could not parse ZonedDateTime") + } + +} diff --git a/adoptium-api-v3-telemetry/pom.xml b/adoptium-api-v3-telemetry/pom.xml index fa1e05e24..bf6b22e79 100644 --- a/adoptium-api-v3-telemetry/pom.xml +++ b/adoptium-api-v3-telemetry/pom.xml @@ -32,10 +32,20 @@ org.slf4j slf4j-api + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + src/main/kotlin - src/test/kotlin diff --git a/adoptium-api-versions/pom.xml b/adoptium-api-versions/pom.xml index 2b365df72..ac4b330c6 100644 --- a/adoptium-api-versions/pom.xml +++ b/adoptium-api-versions/pom.xml @@ -11,12 +11,12 @@ 1.8.1 2.17.2 17 - 4.11.0 + 5.1.2 17 - 1.9.23 + 2.0.10 1.5.6 17 - 3.9.6 + 3.9.8 3.6.2 UTF-8 UTF-8 @@ -101,7 +101,7 @@ io.mockk mockk-jvm - 1.13.10 + 1.13.12 test @@ -164,39 +164,16 @@ - org.litote.kmongo - kmongo-coroutine - ${kmongo.version} - - - org.litote.kmongo - kmongo-flapdoodle - ${kmongo.version} - test - - - org.slf4j - slf4j-simple - - - - junit - junit - - - - org.jetbrains.kotlin - kotlin-test-junit - - + org.mongodb + mongodb-driver-kotlin-coroutine + 5.1.2 + org.jetbrains.kotlin kotlin-test-junit5 ${kotlin.version} - de.flapdoodle.embed de.flapdoodle.embed.mongo @@ -378,11 +355,6 @@ logback-classic ${logback.version} - - org.litote.kmongo - kmongo-id-jackson - ${kmongo.version} - jakarta.json.bind jakarta.json.bind-api diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/pom.xml b/adoptium-frontend-parent/adoptium-api-v3-frontend/pom.xml index 252aa99f0..50c78a48c 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/pom.xml +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/pom.xml @@ -80,17 +80,6 @@ jsonassert test - - org.litote.kmongo - kmongo-flapdoodle - test - - - org.slf4j - slf4j-simple - - - io.mockk mockk-jvm @@ -157,6 +146,17 @@ io.quarkus quarkus-smallrye-openapi + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test-junit5 + ${kotlin.version} + test + @@ -195,18 +195,33 @@ org.jetbrains.kotlin kotlin-maven-plugin + ${kotlin.version} compile + compile compile + + + src/main/kotlin + target/generated-sources/annotations + + test-compile + test-compile test-compile + + + src/test/kotlin + target/generated-test-sources/test-annotations + + diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/FrontEndVersionSupplier.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/FrontEndVersionSupplier.kt index d6f788147..c9ddd6cae 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/FrontEndVersionSupplier.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/FrontEndVersionSupplier.kt @@ -1,4 +1,4 @@ -package net.adoptium.api.v3; +package net.adoptium.api.v3 import jakarta.enterprise.context.ApplicationScoped import jakarta.inject.Inject @@ -9,7 +9,7 @@ import net.adoptium.api.v3.dataSources.VersionSupplier class FrontEndVersionSupplier @Inject constructor( val apiDataStore: APIDataStore ) : VersionSupplier { - override fun getTipVersion(): Int? { + override fun getTipVersion(): Int { return apiDataStore.getReleaseInfo().tip_version } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/Pagination.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/Pagination.kt index dd8296720..48fd70f5d 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/Pagination.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/Pagination.kt @@ -59,7 +59,7 @@ object Pagination { return try { - var totalPages: Int? = null; + var totalPages: Int? = null val chunked = if (showPageCount) { val releasesList = releases.toList() diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/filters/VersionRangeFilter.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/filters/VersionRangeFilter.kt index e8b940f24..4297aca52 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/filters/VersionRangeFilter.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/filters/VersionRangeFilter.kt @@ -23,10 +23,10 @@ class VersionRangeFilter(range: String?, val semver: Boolean) : Predicate { - return Architecture.values().map { it.name }.toList() + return Architecture.entries.map { it.name }.toList() } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/info/TypesOperatingSystemsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/info/TypesOperatingSystemsResource.kt index 79dca7c37..d338c7f92 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/info/TypesOperatingSystemsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/info/TypesOperatingSystemsResource.kt @@ -19,6 +19,6 @@ class TypesOperatingSystemsResource { @Path("/operating_systems") @Operation(summary = "Returns names of operating systems", operationId = "getOperatingSystems") fun get(): List { - return OperatingSystem.values().map { it.name }.toList() + return OperatingSystem.entries.map { it.name }.toList() } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/packages/BinaryResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/packages/BinaryResource.kt index 50fe7582f..addfdeb85 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/packages/BinaryResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/packages/BinaryResource.kt @@ -236,7 +236,7 @@ class BinaryResource @Inject constructor(private val packageEndpoint: PackageEnd return formResponse(if (release == null) emptyList() else listOf(release)) } - protected fun formResponse( + private fun formResponse( releases: List, createResponse: (Package) -> Response = packageEndpoint.redirectToAsset() ): Response { diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt index c48d545b8..92bbfc20a 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/main/kotlin/net/adoptium/api/v3/routes/stats/DownloadStatsResource.kt @@ -131,7 +131,7 @@ class DownloadStatsResource { .getReleases() .filter { it.vendor == Vendor.getDefault() } - if(releaseTypes != null && releaseTypes.isNotEmpty()) { + if(!releaseTypes.isNullOrEmpty()) { releases = releases.filter { releaseTypes.contains(it.release_type) } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsPathTest.kt index f68c020f2..c34d22610 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsPathTest.kt @@ -12,6 +12,7 @@ import net.adoptium.api.v3.models.Vendor import org.hamcrest.Matchers import org.junit.jupiter.api.DynamicTest import org.junit.jupiter.api.TestFactory +import java.util.* import java.util.stream.Stream abstract class AssetsPathTest : FrontendTest() { @@ -24,22 +25,22 @@ abstract class AssetsPathTest : FrontendTest() { @TestFactory fun filtersOs(): Stream { - return runFilterTest("os", OperatingSystem.values()) + return runFilterTest("os", OperatingSystem.entries.toTypedArray()) } @TestFactory fun filtersArchitecture(): Stream { - return runFilterTest("architecture", Architecture.values()) + return runFilterTest("architecture", Architecture.entries.toTypedArray()) } @TestFactory fun filtersImageType(): Stream { - return runFilterTest("image_type", ImageType.values()) + return runFilterTest("image_type", ImageType.entries.toTypedArray()) } @TestFactory fun `filters c_lib`(): Stream { - return runFilterTest("c_lib", CLib.values()) { _, query -> + return runFilterTest("c_lib", CLib.entries.toTypedArray()) { _, query -> "$query&image_type=staticlibs" } } @@ -48,7 +49,7 @@ abstract class AssetsPathTest : FrontendTest() { fun filtersJvmImpl(): Stream { return runFilterTest( "jvm_impl", - JvmImpl.values().filter { JvmImpl.validJvmImpl(it) }.toTypedArray() + JvmImpl.entries.filter { JvmImpl.validJvmImpl(it) }.toTypedArray() ) { value, query -> if (value == JvmImpl.dragonwell) { "$query&vendor=${Vendor.alibaba.name}" @@ -60,7 +61,7 @@ abstract class AssetsPathTest : FrontendTest() { @TestFactory fun filtersHeapSize(): Stream { - return runFilterTest("heap_size", HeapSize.values()) + return runFilterTest("heap_size", HeapSize.entries.toTypedArray()) } @TestFactory @@ -78,7 +79,7 @@ abstract class AssetsPathTest : FrontendTest() { return values .filter { !exclude(it) } .map { value -> - val path2 = customiseQuery(value, "$path?$filterParamName=${value.toString().toLowerCase()}") + val path2 = customiseQuery(value, "$path?$filterParamName=${value.toString().lowercase(Locale.getDefault())}") DynamicTest.dynamicTest(path2) { RestAssured.given() .`when`() diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathSortOrderTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathSortOrderTest.kt index 72ac4eb74..3e942984f 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathSortOrderTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathSortOrderTest.kt @@ -10,7 +10,6 @@ import net.adoptium.api.v3.dataSources.SortOrder import net.adoptium.api.v3.dataSources.models.AdoptRepos import net.adoptium.api.v3.dataSources.models.FeatureRelease import net.adoptium.api.v3.dataSources.models.Releases -import net.adoptium.api.v3.filters.ReleaseFilterFactory import net.adoptium.api.v3.models.Architecture import net.adoptium.api.v3.models.Binary import net.adoptium.api.v3.models.DateTime diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathTest.kt index b6ec4b1e4..262c68b0b 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceFeatureReleasePathTest.kt @@ -35,7 +35,7 @@ class AssetsResourceFeatureReleasePathTest : AssetsPathTest() { .repos .keys .flatMap { version -> - ReleaseType.values() + ReleaseType.entries .map { "/v3/assets/feature_releases/$version/$it" } .map { DynamicTest.dynamicTest(it) { @@ -58,7 +58,7 @@ class AssetsResourceFeatureReleasePathTest : AssetsPathTest() { .repos .keys .flatMap { version -> - ReleaseType.values() + ReleaseType.entries .map { "/v3/assets/feature_releases/$version/$it?PAGE_SIZE=100" } .map { request -> DynamicTest.dynamicTest(request) { @@ -140,7 +140,7 @@ class AssetsResourceFeatureReleasePathTest : AssetsPathTest() { } override fun runFilterTest(filterParamName: String, values: Array, customiseQuery: (T, String) -> String): Stream { - return ReleaseType.values() + return ReleaseType.entries .flatMap { releaseType -> // test the ltses and 1 non-lts listOf(8, 11, 12) diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceReleaseNamePathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceReleaseNamePathTest.kt index 2cc8b29c1..06988b5db 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceReleaseNamePathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AssetsResourceReleaseNamePathTest.kt @@ -9,7 +9,6 @@ import net.adoptium.api.v3.dataSources.APIDataStore import net.adoptium.api.v3.dataSources.SortMethod import net.adoptium.api.v3.dataSources.SortOrder import net.adoptium.api.v3.filters.BinaryFilter -import net.adoptium.api.v3.filters.ReleaseFilterFactory import net.adoptium.api.v3.models.Architecture import net.adoptium.api.v3.models.Release import net.adoptium.api.v3.models.ReleaseType @@ -34,8 +33,7 @@ class AssetsResourceReleaseNamePathTest : FrontendTest() { @TestFactory fun filtersByReleaseNameCorrectly(): Stream { - return Vendor - .values() + return Vendor.entries .flatMap { vendor -> apiDataStore .getAdoptRepos() @@ -43,8 +41,7 @@ class AssetsResourceReleaseNamePathTest : FrontendTest() { .getReleases(releaseFilterFactory.createFilter(vendor = vendor), SortOrder.DESC, SortMethod.DEFAULT) .take(3) .flatMap { release -> - ReleaseType - .values() + ReleaseType.entries .map { "/v3/assets/release_name/$vendor/${release.release_name}" } .map { DynamicTest.dynamicTest(it) { @@ -103,8 +100,8 @@ class AssetsResourceReleaseNamePathTest : FrontendTest() { override fun matchesSafely(p0: String?): Boolean { val returnedRelease = JsonMapper.mapper.readValue(p0, Release::class.java) - return returnedRelease.binaries.filter { it.architecture == Architecture.x32 }.size > 0 && - returnedRelease.binaries.filter { it.architecture != Architecture.x32 }.size == 0 + return returnedRelease.binaries.filter { it.architecture == Architecture.x32 }.isNotEmpty() && + returnedRelease.binaries.filter { it.architecture != Architecture.x32 }.isEmpty() } }) } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AvailableReleasesPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AvailableReleasesPathTest.kt index 0b86156bd..e9eed366d 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AvailableReleasesPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/AvailableReleasesPathTest.kt @@ -2,7 +2,6 @@ package net.adoptium.api import io.quarkus.test.junit.QuarkusTest import io.restassured.RestAssured -import io.restassured.config.RedirectConfig import net.adoptium.api.v3.JsonMapper import net.adoptium.api.v3.models.ReleaseInfo import org.hamcrest.Description diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TestRunner.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TestRunner.kt index 1b2050df5..1ae0284ad 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TestRunner.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TestRunner.kt @@ -31,6 +31,6 @@ class TestRunner : BaseTest() { @Test @Inject fun run() { - Awaitility.await().atMost(Long.MAX_VALUE, TimeUnit.NANOSECONDS).until({ 4 === 5 }) + Awaitility.await().atMost(Long.MAX_VALUE, TimeUnit.NANOSECONDS).until { 4 === 5 } } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesArchitecturesPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesArchitecturesPathTest.kt index c0f6bab2c..c3c39f77f 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesArchitecturesPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesArchitecturesPathTest.kt @@ -18,7 +18,7 @@ class TypesArchitecturesPathTest : FrontendTest() { @Test fun getArchitecturesAreCorrect() { - var body = RestAssured.given() + val body = RestAssured.given() .`when`() .get("/v3/types/architectures") .body @@ -26,7 +26,7 @@ class TypesArchitecturesPathTest : FrontendTest() { val architectures = parseArchitectures(body.asString()) assert(architectures.contains(Architecture.x64.name)) - assert(architectures.size == Architecture.values().size) + assert(architectures.size == Architecture.entries.size) } private fun parseArchitectures(json: String?): List = diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesOperatingSystemsPathTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesOperatingSystemsPathTest.kt index d27d0ca19..b16c12280 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesOperatingSystemsPathTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/TypesOperatingSystemsPathTest.kt @@ -18,7 +18,7 @@ class TypesOperatingSystemsPathTest : FrontendTest() { @Test fun getOperatingSystemsAreCorrect() { - var body = RestAssured.given() + val body = RestAssured.given() .`when`() .get("/v3/types/operating_systems") .body @@ -26,7 +26,7 @@ class TypesOperatingSystemsPathTest : FrontendTest() { val operatingSystems = parseOperatingSystems(body.asString()) assert(operatingSystems.contains(OperatingSystem.linux.name)) - assert(operatingSystems.size == OperatingSystem.values().size) + assert(operatingSystems.size == OperatingSystem.entries.size) } private fun parseOperatingSystems(json: String?): List = diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V1RouteTest.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V1RouteTest.kt index 1ba19ee57..d247ed019 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V1RouteTest.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V1RouteTest.kt @@ -17,12 +17,12 @@ class V1RouteTest : FrontendTest() { "/v1/foo", "/v1/foo/bar" ) - .forEach({ route -> + .forEach { route -> RestAssured.given() .`when`() .get(route) .then() .statusCode(Response.Status.GONE.statusCode) - }) + } } } diff --git a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V3Test.kt b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V3Test.kt index a9e11eb89..81674bb6d 100644 --- a/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V3Test.kt +++ b/adoptium-frontend-parent/adoptium-api-v3-frontend/src/test/kotlin/net/adoptium/api/V3Test.kt @@ -2,11 +2,10 @@ package net.adoptium.api import net.adoptium.api.v3.Startup import net.adoptium.api.v3.Startup.Companion.ENABLE_PERIODIC_UPDATES -import net.adoptium.api.v3.dataSources.APIDataStore import org.jboss.weld.junit5.auto.AddPackages -import org.junit.jupiter.api.extension.ExtendWith -import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith @AddPackages(value=[ApiDataStoreStub::class]) @ExtendWith(value = [DbExtension::class]) diff --git a/adoptium-models-parent/adoptium-api-v3-models/pom.xml b/adoptium-models-parent/adoptium-api-v3-models/pom.xml index 2e3515db1..ffa0a3c27 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/pom.xml +++ b/adoptium-models-parent/adoptium-api-v3-models/pom.xml @@ -38,6 +38,17 @@ org.slf4j slf4j-api + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/AdoptRepos.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/AdoptRepos.kt index 3e91e8216..fd20b556a 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/AdoptRepos.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/AdoptRepos.kt @@ -27,7 +27,6 @@ class AdoptRepos { val releases = repos .asSequence() - .filterNotNull() .map { it.value.releases } .flatMap { it.getReleases() } .toList() @@ -40,9 +39,7 @@ class AdoptRepos { } constructor(list: List) : this( - list - .map { Pair(it.featureVersion, it) } - .toMap() + list.associateBy { it.featureVersion } ) fun getReleases( @@ -99,9 +96,7 @@ class AdoptRepos { other as AdoptRepos - if (repos != other.repos) return false - - return true + return repos == other.repos } override fun hashCode(): Int { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/GitHubId.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/GitHubId.kt index 96ba5ecd1..f4d9ec8fb 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/GitHubId.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/GitHubId.kt @@ -20,9 +20,7 @@ class GitHubId { other as GitHubId - if (id != other.id) return false - - return true + return id == other.id } override fun hashCode(): Int { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/Releases.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/Releases.kt index e446498c4..ecb051a78 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/Releases.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/dataSources/models/Releases.kt @@ -97,9 +97,7 @@ class Releases { other as Releases - if (nodes != other.nodes) return false - - return true + return nodes == other.nodes } override fun hashCode(): Int { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/Architecture.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/Architecture.kt index c9ff0032e..40f2c82df 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/Architecture.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/Architecture.kt @@ -31,9 +31,7 @@ enum class Architecture : FileNameMatcher { @JvmStatic @JsonCreator fun forValue(value: String): Architecture { - return values() - .filter { it.names.contains(value) } - .first() + return entries.first { it.names.contains(value) } } fun getValue(value: String): Architecture { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/DateTime.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/DateTime.kt index 0b66d12e4..db574735b 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/DateTime.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/DateTime.kt @@ -73,9 +73,7 @@ class DateTime { other as DateTime - if (dateTime != other.dateTime) return false - - return true + return dateTime == other.dateTime } override fun hashCode(): Int { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/SourcePackage.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/SourcePackage.kt index 5968e72a9..a5682ac9a 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/SourcePackage.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/SourcePackage.kt @@ -5,12 +5,12 @@ import org.eclipse.microprofile.openapi.annotations.media.Schema class SourcePackage( name: String, link: String, - size: Long) : FileAsset(name, link, size); + size: Long) : FileAsset(name, link, size) class ReleaseNotesPackage( name: String, link: String, - size: Long) : FileAsset(name, link, size); + size: Long) : FileAsset(name, link, size) open class FileAsset { diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/VersionData.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/VersionData.kt index 252f72843..8b7937637 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/VersionData.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/models/VersionData.kt @@ -46,7 +46,7 @@ class VersionData : Comparable { // i.e 11.0.1+11.1 fun formSemver(): String { - var semver = major.toString() + "." + minor + "." + security + var semver = "$major.$minor.$security" if (pre?.isNotEmpty() == true) { semver += "-$pre" diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/VersionParser.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/VersionParser.kt index 4ec0813e7..069e5e95d 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/VersionParser.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/VersionParser.kt @@ -1,10 +1,9 @@ package net.adoptium.api.v3.parser -import net.adoptium.api.v3.models.VersionData -import org.slf4j.LoggerFactory /* ktlint-disable no-wildcard-imports */ -import java.util.* /* ktlint-enable no-wildcard-imports */ +import net.adoptium.api.v3.models.VersionData +import org.slf4j.LoggerFactory import java.util.regex.Matcher import java.util.regex.Pattern @@ -52,7 +51,7 @@ object VersionParser { private fun jep223WithAdoptBuildNum(): List { val buildRegex = "(?[0-9]+)(\\.(?[0-9]+))?" - return Arrays.asList( + return listOf( "(?:jdk\\-)?(?$VNUM_REGEX(\\-$PRE_REGEX)?\\+$buildRegex(\\-$OPT_REGEX)?)", "(?:jdk\\-)?(?$VNUM_REGEX\\-$PRE_REGEX(\\-$OPT_REGEX)?)", "(?:jdk\\-)?(?$VNUM_REGEX(\\+\\-$OPT_REGEX)?)" @@ -60,7 +59,7 @@ object VersionParser { } private fun jep223(): List { - return Arrays.asList( + return listOf( "(?:jdk\\-)?(?$VNUM_REGEX(\\-$PRE_REGEX)?\\+$BUILD_REGEX(\\-$OPT_REGEX)?)", "(?:jdk\\-)?(?$VNUM_REGEX\\-$PRE_REGEX(\\-$OPT_REGEX)?)", "(?:jdk\\-)?(?$VNUM_REGEX(\\+\\-$OPT_REGEX)?)" @@ -104,7 +103,7 @@ object VersionParser { if (version != null) { return version } - } catch (e: Exception) { + } catch (_: Exception) { } throw FailedToParse("Failed to parse $publishName") } @@ -126,7 +125,7 @@ object VersionParser { if (!sanityCheck || sanityCheck(parsed)) { return parsed } - } catch (e: Exception) { + } catch (_: Exception) { } return null } @@ -185,7 +184,7 @@ object VersionParser { private fun sanityCheck(parsed: VersionData): Boolean { - if (!(parsed.major in 101 downTo 7)) { + if (parsed.major !in 101 downTo 7) { // Sanity check as javas parser can match a single number // sane range is 8 to 100 // TODO update me before 2062 and java 100 is released diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/maven/SemverParser.kt b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/maven/SemverParser.kt index 3aadc2618..69722c602 100644 --- a/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/maven/SemverParser.kt +++ b/adoptium-models-parent/adoptium-api-v3-models/src/main/kotlin/net/adoptium/api/v3/parser/maven/SemverParser.kt @@ -1,14 +1,14 @@ -package net.adoptium.api.v3.parser.maven; +package net.adoptium.api.v3.parser.maven import net.adoptium.api.v3.models.VersionData import net.adoptium.api.v3.parser.FailedToParse import java.util.regex.Pattern object SemverParser { - val PRE = """(\-(?
[\.A-Za-z0-9]+))?"""
-    val BUILD = """(\+(?[\.A-Za-z0-9]+))?"""
-    val VERSION_CORE = """(?[0-9]+)\.(?[0-9]+)\.(?[0-9]+)$PRE$BUILD"""
-    val MATCHER = Pattern.compile("^$VERSION_CORE$")
+    private const val PRE = """(\-(?
[\.A-Za-z0-9]+))?"""
+    private const val BUILD = """(\+(?[\.A-Za-z0-9]+))?"""
+    private const val VERSION_CORE = """(?[0-9]+)\.(?[0-9]+)\.(?[0-9]+)$PRE$BUILD"""
+    private val MATCHER = Pattern.compile("^$VERSION_CORE$")
 
     fun parseAdoptSemverNonNull(version: String): VersionData {
         return parseAdoptSemver(version) ?: throw FailedToParse("Failed to parse $version")
@@ -49,7 +49,7 @@ object SemverParser {
 
                         optional = if (parts.size > 2) parts[2] else null
                         adoptBuildNum = if (parts.size > 1) parts[1].toInt() else null
-                        build = if (parts.size > 0) parts[0].toInt() else null
+                        build = if (parts.isNotEmpty()) parts[0].toInt() else null
 
                         if (build != null) {
                             patch = build / 100
diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/SemverParserTest.kt b/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/SemverParserTest.kt
similarity index 99%
rename from adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/SemverParserTest.kt
rename to adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/SemverParserTest.kt
index 5bb85b1ff..df1b28c60 100644
--- a/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/SemverParserTest.kt
+++ b/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/SemverParserTest.kt
@@ -1,4 +1,4 @@
-package api;
+package net.adoptium.api
 
 import net.adoptium.api.v3.models.VersionData
 import net.adoptium.api.v3.parser.VersionParser
diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/VersionParserTest.kt b/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/VersionParserTest.kt
similarity index 100%
rename from adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/VersionParserTest.kt
rename to adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/VersionParserTest.kt
diff --git a/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/VersionRangeTest.kt b/adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/VersionRangeTest.kt
similarity index 100%
rename from adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/api/VersionRangeTest.kt
rename to adoptium-models-parent/adoptium-api-v3-models/src/test/kotlin/net/adoptium/api/VersionRangeTest.kt
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/pom.xml b/adoptium-updater-parent/adoptium-api-v3-updater/pom.xml
index b4fbf4f96..a0bbbce6e 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/pom.xml
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/pom.xml
@@ -74,17 +74,6 @@
             weld-junit5
             test
         
-        
-            org.litote.kmongo
-            kmongo-flapdoodle
-            test
-            
-                
-                    org.slf4j
-                    slf4j-simple
-                
-            
-        
         
             io.mockk
             mockk-jvm
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptReposBuilder.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptReposBuilder.kt
index 1f64e338e..6a6a1bf4b 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptReposBuilder.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptReposBuilder.kt
@@ -1,6 +1,5 @@
 package net.adoptium.api.v3
 
-import ReleaseIncludeFilter
 import jakarta.enterprise.context.ApplicationScoped
 import jakarta.inject.Inject
 import net.adoptium.api.v3.dataSources.VersionSupplier
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptRepository.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptRepository.kt
index f528a0696..91e39fa09 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptRepository.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/AdoptRepository.kt
@@ -1,6 +1,5 @@
 package net.adoptium.api.v3
 
-import ReleaseIncludeFilter
 import jakarta.enterprise.context.ApplicationScoped
 import jakarta.inject.Inject
 import kotlinx.coroutines.Deferred
@@ -76,7 +75,7 @@ open class AdoptRepositoryImpl @Inject constructor(
     override suspend fun getReleaseById(gitHubId: GitHubId): ReleaseResult? {
         val release = client.getReleaseById(gitHubId)
 
-        if (release == null) return null;
+        if (release == null) return null
 
         return getMapperForRepo(release.url)
             .toAdoptRelease(release)
@@ -147,7 +146,7 @@ open class AdoptRepositoryImpl @Inject constructor(
         }
     }
 
-    private suspend fun  getDataForEachRepo(
+    private fun  getDataForEachRepo(
         version: Int,
         filter: ReleaseIncludeFilter,
         getFun: suspend (Vendor, String, String) -> E
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/ReleaseIncludeFilter.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/ReleaseIncludeFilter.kt
index 566c27f9e..949040caa 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/ReleaseIncludeFilter.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/ReleaseIncludeFilter.kt
@@ -1,4 +1,5 @@
-import net.adoptium.api.v3.TimeSource
+package net.adoptium.api.v3
+
 import net.adoptium.api.v3.config.APIConfig
 import net.adoptium.api.v3.mapping.ReleaseMapper
 import net.adoptium.api.v3.models.Vendor
@@ -24,10 +25,10 @@ class ReleaseIncludeFilter(
     }
 
     fun filterVendor(vendor: Vendor): Boolean {
-        if (includeAll || APIConfig.UPDATE_ADOPTOPENJDK) {
-            return true // include all vendors
+        return if (includeAll || APIConfig.UPDATE_ADOPTOPENJDK) {
+            true // include all vendors
         } else {
-            return !excludedVendors.contains(vendor)
+            !excludedVendors.contains(vendor)
         }
     }
 
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/V3Updater.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/V3Updater.kt
index a3ea1f1ba..1764c6ed8 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/V3Updater.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/V3Updater.kt
@@ -1,7 +1,5 @@
 package net.adoptium.api.v3
 
-import ReleaseFilterType
-import ReleaseIncludeFilter
 import io.quarkus.arc.profile.UnlessBuildProfile
 import io.quarkus.runtime.Startup
 import jakarta.enterprise.context.ApplicationScoped
@@ -76,10 +74,6 @@ class V3Updater @Inject constructor(
                 .toList())
     }
 
-    init {
-        //AppInsightsTelemetry.start()
-    }
-
     override fun addToUpdate(toUpdate: String): List {
         val repo = apiDataStore.loadDataFromDb(true)
         val toUpdateList = repo
@@ -145,10 +139,10 @@ class V3Updater @Inject constructor(
             .forEach { releaseA ->
                 val releaseB = repoB.allReleases.getReleaseById(releaseA.id)
                 if (releaseB == null) {
-                    LOGGER.debug("Release disapeared ${releaseA.id} ${releaseA.version_data.semver}")
+                    LOGGER.debug("Release disappeared ${releaseA.id} ${releaseA.version_data.semver}")
                 } else if (releaseA != releaseB) {
-                    LOGGER.debug("Release changedA $releaseA")
-                    LOGGER.debug("Release changedB $releaseB")
+                    LOGGER.debug("Release changedA {}", releaseA)
+                    LOGGER.debug("Release changedB {}", releaseB)
                     releaseA
                         .binaries
                         .forEach { binaryA ->
@@ -242,7 +236,7 @@ class V3Updater @Inject constructor(
         )
     }
 
-    fun fullUpdate(currentRepo: AdoptRepos, releasesOnly: Boolean): AdoptRepos? {
+    private fun fullUpdate(currentRepo: AdoptRepos, releasesOnly: Boolean): AdoptRepos? {
         // Must catch errors or may kill the scheduler
         try {
             return runBlocking {
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/ReleaseVersionResolver.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/ReleaseVersionResolver.kt
index 0c1ef8c0a..913c8dba3 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/ReleaseVersionResolver.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/ReleaseVersionResolver.kt
@@ -11,7 +11,7 @@ class ReleaseVersionResolver @Inject constructor(
     private val versionSupplier: VersionSupplier
 ) {
 
-    suspend fun formReleaseInfo(repo: AdoptRepos): ReleaseInfo {
+    fun formReleaseInfo(repo: AdoptRepos): ReleaseInfo {
         val gaReleases = repo
             .allReleases
             .getReleases()
@@ -26,7 +26,7 @@ class ReleaseVersionResolver @Inject constructor(
             .toTypedArray()
         val mostRecentFeatureRelease: Int = availableReleases.lastOrNull() ?: 0
 
-        val ltsVersions = versionSupplier.getLtsVersions();
+        val ltsVersions = versionSupplier.getLtsVersions()
 
         val availableLtsReleases: Array = gaReleases
             .asSequence()
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdatableVersionSupplierImpl.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdatableVersionSupplierImpl.kt
index eb15c6be7..6d51b22f9 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdatableVersionSupplierImpl.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdatableVersionSupplierImpl.kt
@@ -9,7 +9,7 @@ import org.slf4j.LoggerFactory
 @ApplicationScoped
 class UpdatableVersionSupplierImpl @Inject constructor(val updaterHtmlClient: UpdaterHtmlClient) : VersionSupplier, UpdatableVersionSupplier {
     companion object {
-        private val LOGGER: Logger = LoggerFactory.getLogger(UpdatableVersionSupplierImpl::class.java);
+        private val LOGGER: Logger = LoggerFactory.getLogger(UpdatableVersionSupplierImpl::class.java)
     }
 
     private val DEFAULT_LATEST_JAVA_VERSION = 24
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/stats/GitHubDownloadStatsCalculator.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/stats/GitHubDownloadStatsCalculator.kt
index f56aa7eb6..552f1b1a7 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/stats/GitHubDownloadStatsCalculator.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/main/kotlin/net/adoptium/api/v3/stats/GitHubDownloadStatsCalculator.kt
@@ -1,6 +1,7 @@
 package net.adoptium.api.v3.stats
 
 import jakarta.enterprise.context.ApplicationScoped
+import jakarta.inject.Inject
 import net.adoptium.api.v3.TimeSource
 import net.adoptium.api.v3.dataSources.models.AdoptRepos
 import net.adoptium.api.v3.dataSources.persitence.ApiPersistence
@@ -9,7 +10,6 @@ import net.adoptium.api.v3.models.JvmImpl
 import net.adoptium.api.v3.models.Vendor
 import org.slf4j.LoggerFactory
 import java.time.ZonedDateTime
-import jakarta.inject.Inject
 
 @ApplicationScoped
 open class GitHubDownloadStatsCalculator @Inject constructor(private val database: ApiPersistence) {
@@ -32,7 +32,7 @@ open class GitHubDownloadStatsCalculator @Inject constructor(private val databas
         val stats = repos
             .repos
             .values
-            .map { featureRelease ->
+            .sumOf { featureRelease ->
                 val total = featureRelease
                     .releases
                     .getReleases()
@@ -48,7 +48,6 @@ open class GitHubDownloadStatsCalculator @Inject constructor(private val databas
                 LOGGER.info("Stats ${featureRelease.featureVersion} $total")
                 total
             }
-            .sum()
         LOGGER.info("Stats total $stats")
     }
 
@@ -67,21 +66,21 @@ open class GitHubDownloadStatsCalculator @Inject constructor(private val databas
                     }
 
                 // Tally up jvmImpl download stats
-                val jvmImplMap: Map = JvmImpl.values().map { jvmImpl ->
-                    jvmImpl to
-                            featureRelease
-                                .releases
-                                .getReleases()
-                                .filter { it.vendor == Vendor.getDefault() }
-                                .sumOf {
-                                    it.binaries
-                                        .filter { binary -> binary.jvm_impl == jvmImpl }
-                                        .sumOf { binary ->
-                                            binary.download_count.toInt()
-                                        }
-                                }
+                val jvmImplMap: Map = JvmImpl.entries
+                    .associateWith { jvmImpl ->
+                        featureRelease
+                            .releases
+                            .getReleases()
+                            .filter { it.vendor == Vendor.getDefault() }
+                            .sumOf {
+                                it.binaries
+                                    .filter { binary -> binary.jvm_impl == jvmImpl }
+                                    .sumOf { binary ->
+                                        binary.download_count.toInt()
+                                    }
+                            }
                             .toLong()
-                }.toMap()
+                    }
 
                 GitHubDownloadStatsDbEntry(
                     date,
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/APIDataStoreTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/APIDataStoreTest.kt
index 86b6ac46a..0341f1097 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/APIDataStoreTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/APIDataStoreTest.kt
@@ -27,7 +27,7 @@ class APIDataStoreTest : MongoTest() {
     fun reposHasElements() {
         runBlocking {
             val repo = BaseTest.adoptRepos
-            assert(repo.getFeatureRelease(8)!!.releases.getReleases().toList().size > 0)
+            assert(repo.getFeatureRelease(8)!!.releases.getReleases().toList().isNotEmpty())
         }
     }
 
@@ -77,6 +77,6 @@ class APIDataStoreTest : MongoTest() {
 
     @Test
     fun `update is not scheduled by default`(apiDataStore: APIDataStoreImpl) {
-        assertNull(apiDataStore.schedule)
+        assertNull(apiDataStore.getSchedule())
     }
 }
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptMetadataVersionParsingTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptMetadataVersionParsingTest.kt
index d225eee13..b890a3c2a 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptMetadataVersionParsingTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptMetadataVersionParsingTest.kt
@@ -23,7 +23,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
 class AdoptMetadataVersionParsingTest : BaseTest() {
 
     val client: UpdaterHtmlClient = object : UpdaterHtmlClient {
-        override suspend fun get(url: String): String? {
+        override suspend fun get(url: String): String {
             return """
                         {
                             "WARNING": "THIS METADATA FILE IS STILL IN ALPHA DO NOT USE ME",
@@ -49,10 +49,10 @@ class AdoptMetadataVersionParsingTest : BaseTest() {
             """.trimIndent()
         }
 
-        override suspend fun getFullResponse(request: UrlRequest): HttpResponse? {
+        override suspend fun getFullResponse(request: UrlRequest): HttpResponse {
             val metadataResponse = mockk()
             val entity = mockk()
-            every { entity.content } returns get(request.url)?.byteInputStream()
+            every { entity.content } returns get(request.url).byteInputStream()
             every { metadataResponse.statusLine } returns BasicStatusLine(ProtocolVersion("", 1, 1), 200, "")
             every { metadataResponse.entity } returns entity
             every { metadataResponse.getFirstHeader("Last-Modified") } returns BasicHeader("Last-Modified", "Thu, 01 Jan 1970 00:00:00 GMT")
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseMapperTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseMapperTest.kt
index 79e579bfd..1b88224ef 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseMapperTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseMapperTest.kt
@@ -197,11 +197,11 @@ class AdoptReleaseMapperTest : BaseTest() {
 
     private fun buildGhAssets(assetNames: List>) =
         GHAssets(assetNames
-            .map { it ->
+            .map {
                 GHAsset(
                     it.first,
                     1L,
-                    "${it.second}",
+                    it.second,
                     1L,
                     "2013-02-27T19:35:32Z"
                 )
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseNotesTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseNotesTest.kt
index f40b53612..8699ad6ca 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseNotesTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReleaseNotesTest.kt
@@ -1,6 +1,6 @@
 package net.adoptium.api
 
-import ReleaseIncludeFilter
+import net.adoptium.api.v3.ReleaseIncludeFilter
 import kotlinx.coroutines.runBlocking
 import net.adoptium.api.testDoubles.InMemoryApiPersistence
 import net.adoptium.api.v3.AdoptRepository
@@ -57,7 +57,7 @@ class AdoptReleaseNotesTest : BaseTest() {
                                 ]
                             """.trimIndent()
             } else {
-                return null;
+                return null
             }
         }
 
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposBuilderTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposBuilderTest.kt
index 23a5a56a3..8e69ef132 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposBuilderTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposBuilderTest.kt
@@ -84,12 +84,9 @@ class AdoptReposBuilderTest : BaseTest() {
     fun updatedReleaseIsNotUpdatedWhenThingsDontChange() {
         runBlocking {
 
-            val updated2 = runBlocking {
-                adoptReposBuilder.incrementalUpdate(emptySet(), before) { null }
-            }
-            val updated3 = runBlocking {
-                adoptReposBuilder.incrementalUpdate(emptySet(), before) { null }
-            }
+            val updated2 = adoptReposBuilder.incrementalUpdate(emptySet(), before) { null }
+
+            val updated3 = adoptReposBuilder.incrementalUpdate(emptySet(), before) { null }
 
             assertTrue { updated == updated2 }
             assertTrue { updated2 == updated3 }
@@ -99,7 +96,7 @@ class AdoptReposBuilderTest : BaseTest() {
     @Test
     fun `young releases continue to be pulled`() {
         runBlocking {
-            val repo = stub.repo;
+            val repo = stub.repo
             val adoptRepository = AdoptRepositoryStub()
             val adoptRepo = spyk(adoptRepository)
             val adoptReposBuilder = AdoptReposBuilder(adoptRepo, UpdatableVersionSupplierStub())
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposTestDataGenerator.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposTestDataGenerator.kt
index 2144e8b24..831553cfc 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposTestDataGenerator.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/AdoptReposTestDataGenerator.kt
@@ -28,7 +28,7 @@ object AdoptReposTestDataGenerator {
     private val TEST_VERSIONS = listOf(8, 10, 11, 12)
     private val TEST_RESOURCES = listOf(
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.adoptopenjdk),
             listOf(Project.jdk),
             listOf(JvmImpl.hotspot),
@@ -38,17 +38,17 @@ object AdoptReposTestDataGenerator {
             listOf(HeapSize.normal),
         ),
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.adoptopenjdk),
             listOf(Project.jdk),
             listOf(JvmImpl.openj9),
             listOf(ImageType.jre, ImageType.jdk),
             listOf(Architecture.x64, Architecture.x32, Architecture.arm),
             listOf(OperatingSystem.linux, OperatingSystem.mac, OperatingSystem.windows),
-            HeapSize.values().asList()
+            HeapSize.entries
         ),
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.openjdk),
             listOf(Project.jdk),
             listOf(JvmImpl.hotspot),
@@ -59,7 +59,7 @@ object AdoptReposTestDataGenerator {
             listOf(8, 11)
         ),
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.alibaba),
             listOf(Project.jdk),
             listOf(JvmImpl.dragonwell),
@@ -70,7 +70,7 @@ object AdoptReposTestDataGenerator {
             listOf(8, 11)
         ),
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.eclipse),
             listOf(Project.jdk),
             listOf(JvmImpl.hotspot),
@@ -81,7 +81,7 @@ object AdoptReposTestDataGenerator {
             listOf(8, 11, 12)
         ),
         PermittedValues(
-            ReleaseType.values().asList(),
+            ReleaseType.entries,
             listOf(Vendor.eclipse),
             listOf(Project.jdk),
             listOf(JvmImpl.hotspot),
@@ -232,7 +232,7 @@ object AdoptReposTestDataGenerator {
         }
 
         private fun exhaustiveBinaryList(): List {
-            return HeapSize.values()
+            return HeapSize.entries
                 .map {
                     Binary(
                         createPackage(),
@@ -250,7 +250,7 @@ object AdoptReposTestDataGenerator {
                     )
                 }
                 .union(
-                    OperatingSystem.values()
+                    OperatingSystem.entries
                         .map {
                             Binary(
                                 createPackage(),
@@ -269,7 +269,7 @@ object AdoptReposTestDataGenerator {
                         }
                 )
                 .union(
-                    Architecture.values()
+                    Architecture.entries
                         .map {
                             Binary(
                                 createPackage(),
@@ -288,7 +288,7 @@ object AdoptReposTestDataGenerator {
                         }
                 )
                 .union(
-                    ImageType.values()
+                    ImageType.entries
                         .map {
                             Binary(
                                 createPackage(),
@@ -307,7 +307,7 @@ object AdoptReposTestDataGenerator {
                         }
                 )
                 .union(
-                    JvmImpl.values()
+                    JvmImpl.entries
                         .map {
                             Binary(
                                 createPackage(),
@@ -326,7 +326,7 @@ object AdoptReposTestDataGenerator {
                         }
                 )
                 .union(
-                    Project.values()
+                    Project.entries
                         .map {
                             Binary(
                                 createPackage(),
@@ -383,6 +383,7 @@ object AdoptReposTestDataGenerator {
                 return emptyList()
             }
             return releaseType
+                .asSequence()
                 .map { releaseBuilder()(it) }
                 .flatMap { builder -> vendor.map { builder(it) } }
                 .flatMap { builder -> getVersions(majorVersion).map { builder(it) } }
@@ -390,6 +391,7 @@ object AdoptReposTestDataGenerator {
                 .filter {
                     Vendor.validVendor(it.vendor)
                 }
+                .toList()
         }
 
         private fun getBinaries(): Array {
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/BaseTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/BaseTest.kt
index aebee413f..d9a556d96 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/BaseTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/BaseTest.kt
@@ -52,7 +52,7 @@ abstract class BaseTest {
                 return null
             }
 
-            override suspend fun getFullResponse(request: UrlRequest): HttpResponse? {
+            override suspend fun getFullResponse(request: UrlRequest): HttpResponse {
                 val metadataResponse = mockk()
 
                 val entity = mockk()
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/CachedGitHubHtmlClientTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/CachedGitHubHtmlClientTest.kt
index 23cda7411..c8718de7c 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/CachedGitHubHtmlClientTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/CachedGitHubHtmlClientTest.kt
@@ -1,6 +1,5 @@
 package net.adoptium.api
 
-import io.mockk.Called
 import io.mockk.coEvery
 import io.mockk.coVerify
 import io.mockk.confirmVerified
@@ -15,14 +14,14 @@ import net.adoptium.api.v3.dataSources.UpdaterHtmlClient
 import net.adoptium.api.v3.dataSources.UrlRequest
 import net.adoptium.api.v3.dataSources.github.CachedGitHubHtmlClient
 import net.adoptium.api.v3.dataSources.mongo.CacheDbEntry
+import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Assertions.assertNull
 import org.junit.jupiter.api.DynamicTest
 import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.TestFactory
 import org.junit.jupiter.api.extension.ExtendWith
 import java.time.ZonedDateTime
 import java.util.stream.Stream
-import org.junit.jupiter.api.Assertions.assertEquals
-import org.junit.jupiter.api.Assertions.assertNull
 
 @ExtendWith(MockKExtension::class)
 class CachedGitHubHtmlClientTest {
@@ -115,9 +114,11 @@ class CachedGitHubHtmlClientTest {
                 while (client.getQueueLength() > 0) {
                     delay(1000)
                 }
-                coVerify(timeout = 3000) {
-                    updaterHtmlClient.getFullResponse(request)?.wasNot(Called)
+
+                coVerify(timeout = 3000, exactly = 0) {
+                    updaterHtmlClient.getFullResponse(request)
                 }
+
                 confirmVerified(updaterHtmlClient)
             }
         }
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DateTimeMigrationTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DateTimeMigrationTest.kt
index 8064d0178..dbfcfca58 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DateTimeMigrationTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DateTimeMigrationTest.kt
@@ -1,23 +1,28 @@
 package net.adoptium.api
 
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.runBlocking
 import net.adoptium.api.v3.JsonMapper
 import net.adoptium.api.v3.TimeSource
 import net.adoptium.api.v3.dataSources.persitence.mongo.MongoClient
 import net.adoptium.api.v3.models.DateTime
+import org.bson.Document
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Test
 import java.time.Instant
 import java.time.ZoneOffset
 import java.time.ZonedDateTime
-import java.util.UUID
+import java.util.*
 import java.util.concurrent.TimeUnit
 
-class DateTimeMigrationTest : MongoTest() {
+data class HasZonedDateTime(
+    val zdt: ZonedDateTime)
+
+data class HasDateTime(
+    val zdt: DateTime)
 
-    class HasZonedDateTime(val zdt: ZonedDateTime)
+class DateTimeMigrationTest : MongoTest() {
 
-    class HasDateTime(val zdt: DateTime)
 
     @Test
     fun `can serialize as zdt and deserialize as DateTime`() {
@@ -39,17 +44,17 @@ class DateTimeMigrationTest : MongoTest() {
                     .minus(1, TimeUnit.MILLISECONDS.toChronoUnit())
 
                 val hzdt = HasZonedDateTime(date)
-                val client1 = mongoClient.database.getCollection(collectionName)
+                val client1 = mongoClient.getDatabase().getCollection(collectionName)
                 client1.insertOne(hzdt)
 
-                val hzdt2 = client1.findOne()
+                val hzdt2 = client1.find().firstOrNull()
                 assertEquals(hzdt.zdt, hzdt2?.zdt)
 
-                val client2 = mongoClient.database.getCollection(collectionName)
-                val fromDb = client2.findOne("{}")
-                assertEquals(hzdt.zdt, fromDb?.zdt?.dateTime)
+                val client2 = mongoClient.getDatabase().getCollection(collectionName)
+                val fromDb = client2.find().firstOrNull()
+                assertEquals(hzdt.zdt, fromDb?.zdt)
             } finally {
-                mongoClient.database.dropCollection(collectionName)
+                mongoClient.getDatabase().getCollection(collectionName).drop()
             }
         }
     }
@@ -67,22 +72,22 @@ class DateTimeMigrationTest : MongoTest() {
         runBlocking {
             try {
                 val hzdt = HasZonedDateTime(TimeSource.now())
-                val client1 = mongoClient.database.getCollection(collectionName)
+                val client1 = mongoClient.getDatabase().getCollection(collectionName)
                 client1.insertOne(hzdt)
 
-                val hzdt2 = client1.findOne()
+                val hzdt2 = client1.find().firstOrNull()
                 assertEquals(hzdt.zdt, hzdt2?.zdt)
 
-                val client2 = mongoClient.database.getCollection(collectionName)
-                val fromDb = client2.findOne("{}")
-                assertEquals(hzdt.zdt, fromDb?.zdt?.dateTime)
+                val client2 = mongoClient.getDatabase().getCollection(collectionName)
+                val fromDb = client2.find(Document.parse("{}")).firstOrNull()
+                assertEquals(hzdt.zdt, fromDb?.zdt)
 
-                client2.deleteMany()
+                client2.deleteMany(Document.parse("{}"))
                 client2.insertOne(fromDb!!)
-                val fromDb2 = client2.findOne("{}")
-                assertEquals(fromDb.zdt.dateTime, fromDb2?.zdt?.dateTime)
+                val fromDb2 = client2.find(Document.parse("{}")).firstOrNull()
+                assertEquals(fromDb.zdt, fromDb2?.zdt)
             } finally {
-                mongoClient.database.dropCollection(collectionName)
+                mongoClient.getDatabase().getCollection(collectionName).drop()
             }
         }
     }
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DockerStatsInterfaceTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DockerStatsInterfaceTest.kt
index 2eb616b07..04cd682e7 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DockerStatsInterfaceTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/DockerStatsInterfaceTest.kt
@@ -34,7 +34,7 @@ class DockerStatsInterfaceTest : BaseTest() {
             dockerStatsInterface.updateDb()
 
             val stats = apiPersistence.getLatestAllDockerStats()
-            Assertions.assertTrue(stats.size > 0)
+            Assertions.assertTrue(stats.isNotEmpty())
         }
     }
 
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/GraphQLGitHubReleaseClientTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/GraphQLGitHubReleaseClientTest.kt
index bf1890a25..59ff296bb 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/GraphQLGitHubReleaseClientTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/GraphQLGitHubReleaseClientTest.kt
@@ -1,7 +1,7 @@
 package net.adoptium.api
 
-import ReleaseFilterType
-import ReleaseIncludeFilter
+import net.adoptium.api.v3.ReleaseFilterType
+import net.adoptium.api.v3.ReleaseIncludeFilter
 import com.expediagroup.graphql.client.types.GraphQLClientRequest
 import com.expediagroup.graphql.client.types.GraphQLClientResponse
 import io.mockk.coEvery
@@ -124,14 +124,14 @@ class GraphQLGitHubReleaseClientTest : BaseTest() {
                     every { builder.errors } returns null
                     return builder
                 }
-            };
+            }
 
             val graphQLGitHubInterface = GraphQLGitHubInterface(graphQLRequest, mockkHttpClient())
             val graphQLGitHubReleaseRequest = GraphQLGitHubReleaseRequest(graphQLGitHubInterface)
 
             val client = GraphQLGitHubRepositoryClient(graphQLGitHubInterface, graphQLGitHubReleaseRequest)
 
-            val repo = client.getRepository(AdoptRepositoryImpl.ADOPT_ORG, "a-repo-name", { _, _ -> true })
+            val repo = client.getRepository(AdoptRepositoryImpl.ADOPT_ORG, "a-repo-name") { _, _ -> true }
 
             assertEquals(Companion.repo, repo)
         }
@@ -208,7 +208,7 @@ class GraphQLGitHubReleaseClientTest : BaseTest() {
 
             val client = GraphQLGitHubRepositoryClient(graphQLGitHubInterface, graphQLGitHubReleaseRequest)
 
-            val repo = client.getRepository(AdoptRepositoryImpl.ADOPT_ORG, "a-repo-name", { _, _ -> true })
+            val repo = client.getRepository(AdoptRepositoryImpl.ADOPT_ORG, "a-repo-name") { _, _ -> true }
 
             assertEquals(2, repo.releases.releases.size)
         }
@@ -307,7 +307,7 @@ class GraphQLGitHubReleaseClientTest : BaseTest() {
                 every { builder.errors } returns null
                 return builder
             }
-        };
+        }
 
         val graphQLGitHubInterface = GraphQLGitHubInterface(graphQLRequest, mockkHttpClient())
         val graphQLGitHubReleaseRequest = GraphQLGitHubReleaseRequest(graphQLGitHubInterface)
@@ -315,7 +315,7 @@ class GraphQLGitHubReleaseClientTest : BaseTest() {
         val client = GraphQLGitHubRepositoryClient(graphQLGitHubInterface, graphQLGitHubReleaseRequest)
 
 
-        val htmlClient = mockk();
+        val htmlClient = mockk()
         coEvery { htmlClient.getUrl(any()) }.returns(null)
 
         val adoptReleaseMapperFactory = mockk()
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/InternalDbStoreTests.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/InternalDbStoreTests.kt
index a51196edc..639431528 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/InternalDbStoreTests.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/InternalDbStoreTests.kt
@@ -5,16 +5,15 @@ import net.adoptium.api.v3.TimeSource
 import net.adoptium.api.v3.dataSources.mongo.CacheDbEntry
 import net.adoptium.api.v3.dataSources.mongo.InternalDbStoreImpl
 import net.adoptium.api.v3.dataSources.persitence.mongo.MongoClient
-import org.junit.jupiter.api.Assertions
-import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 class InternalDbStoreTests : MongoTest() {
 
     @Test
-    fun `checked time is set`(mongoClient: MongoClient) {
+    fun `checked time is set`() {
         runBlocking {
-            val internalDbStore = InternalDbStoreImpl(mongoClient)
+            val internalDbStore = InternalDbStoreImpl(MongoClient())
 
             val now = TimeSource.now()
             val data = CacheDbEntry("foo", "bar", now, "some data")
@@ -30,7 +29,7 @@ class InternalDbStoreTests : MongoTest() {
             internalDbStore.updateCheckedTime("foo", newTime)
             val updated = internalDbStore.getCachedWebpage("foo")
 
-            Assertions.assertEquals(CacheDbEntry(data.url, data.lastModified, newTime, data.data), updated)
+            assertEquals(CacheDbEntry(data.url, data.lastModified, newTime, data.data), updated)
         }
     }
 }
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MetadataSerializationTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MetadataSerializationTest.kt
index d7e5aa52b..f56b4f692 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MetadataSerializationTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MetadataSerializationTest.kt
@@ -55,7 +55,7 @@ class MetadataSerializationTest {
         val metadata = generateMetadata()
 
         val serialized = UpdaterJsonMapper.mapper.writeValueAsString(metadata)
-        var json = UpdaterJsonMapper.mapper.readValue(serialized, ObjectNode::class.java)
+        val json = UpdaterJsonMapper.mapper.readValue(serialized, ObjectNode::class.java)
         json.remove("WARNING")
 
         val noWarning = GHMetaData(null, metadata.os, metadata.arch, metadata.variant, metadata.version, metadata.scmRef, metadata.version_data, metadata.binary_type, metadata.sha256)
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoAPIPersistenceTests.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoAPIPersistenceTests.kt
index 3cd0ee542..fc8082866 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoAPIPersistenceTests.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoAPIPersistenceTests.kt
@@ -4,16 +4,15 @@ import kotlinx.coroutines.runBlocking
 import net.adoptium.api.v3.TimeSource
 import net.adoptium.api.v3.dataSources.models.GitHubId
 import net.adoptium.api.v3.dataSources.persitence.mongo.MongoApiPersistence
+import net.adoptium.api.v3.dataSources.persitence.mongo.MongoClient
 import net.adoptium.api.v3.models.GHReleaseMetadata
-import org.junit.jupiter.api.Assertions
-import org.junit.jupiter.api.Test
 import org.junit.jupiter.api.Assertions.assertEquals
+import org.junit.jupiter.api.Test
 
 class MongoAPIPersistenceTests : MongoTest() {
     @Test
-    fun `update time is set`(apiPersistence: MongoApiPersistence) {
+    fun `update time is set`(api: MongoApiPersistence) {
         runBlocking {
-            val api = apiPersistence
             api.updateUpdatedTime(TimeSource.now(), "", 0)
             api.updateUpdatedTime(TimeSource.now(), "", 0)
             api.updateUpdatedTime(TimeSource.now(), "", 0)
@@ -22,19 +21,21 @@ class MongoAPIPersistenceTests : MongoTest() {
 
             val stored = api.getUpdatedAt()
 
-            Assertions.assertEquals(time, stored.time)
+            assertEquals(time, stored.time)
         }
     }
 
     @Test
-    fun `metadata is persisted`(apiPersistence: MongoApiPersistence) {
+    fun `metadata is persisted`() {
         runBlocking {
+            val apiPersistence = MongoApiPersistence(MongoClient())
 
             val metadata = GHReleaseMetadata(10, GitHubId("foo"))
             apiPersistence.setGhReleaseMetadata(metadata)
 
             val saved = apiPersistence.getGhReleaseMetadata(GitHubId("foo"))
 
+
             assertEquals(metadata, saved)
         }
     }
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoTest.kt
index c823b2c99..7c1a6d854 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/MongoTest.kt
@@ -4,7 +4,6 @@ import de.flapdoodle.embed.mongo.config.Net
 import de.flapdoodle.embed.mongo.distribution.Version
 import de.flapdoodle.embed.mongo.transitions.Mongod
 import de.flapdoodle.embed.mongo.transitions.RunningMongodProcess
-import de.flapdoodle.embed.process.runtime.Network
 import de.flapdoodle.reverse.transitions.Start
 import net.adoptium.api.testDoubles.UpdatableVersionSupplierStub
 import net.adoptium.api.v3.dataSources.APIDataStoreImpl
@@ -34,12 +33,13 @@ abstract class MongoTest {
         @JvmStatic
         fun startFongo() {
             val bindIp = "localhost"
-            val net = Net.of("localhost",
-                Network.freeServerPort(Network.getLocalHost()),
-                Network.localhostIsIPv6()
-            )
 
-            val mongodbTestConnectionString = "mongodb://$bindIp:${net.port}"
+            val port = de.flapdoodle.net.Net.freeServerPort()
+
+            val net = Net.builder().bindIp(bindIp).port(port).isIpv6(false).build()
+
+            val mongodbTestConnectionString = "mongodb://$bindIp:$port"
+
             LOGGER.info("Mongo test connection string - $mongodbTestConnectionString")
             System.setProperty("MONGODB_TEST_CONNECTION_STRING", mongodbTestConnectionString)
 
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/UpdateRunner.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/UpdateRunner.kt
index 9c3c72f25..7f5c56121 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/UpdateRunner.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/UpdateRunner.kt
@@ -3,6 +3,7 @@ package net.adoptium.api
 import kotlinx.coroutines.runBlocking
 import net.adoptium.api.testDoubles.InMemoryInternalDbStore
 import net.adoptium.api.v3.AdoptRepositoryImpl
+import net.adoptium.api.v3.ReleaseIncludeFilter
 import net.adoptium.api.v3.V3Updater
 import net.adoptium.api.v3.dataSources.DefaultUpdaterHtmlClient
 import net.adoptium.api.v3.dataSources.HttpClientFactory
@@ -35,7 +36,7 @@ class UpdateRunner {
     fun run(updater: V3Updater) {
         System.clearProperty("GITHUB_TOKEN")
         updater.run(false)
-        Awaitility.await().atMost(Long.MAX_VALUE, TimeUnit.NANOSECONDS).until({ 4 == 5 })
+        Awaitility.await().atMost(Long.MAX_VALUE, TimeUnit.NANOSECONDS).until { 4 == 5 }
     }
 
     @Test
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/V3UpdaterTest.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/V3UpdaterTest.kt
index 852807df3..75997d588 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/V3UpdaterTest.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/V3UpdaterTest.kt
@@ -1,7 +1,8 @@
 package net.adoptium.api
 
-import ReleaseIncludeFilter
+import net.adoptium.api.v3.ReleaseIncludeFilter
 import kotlinx.coroutines.runBlocking
+import net.adoptium.api.v3.ReleaseFilterType
 import net.adoptium.api.v3.TimeSource
 import net.adoptium.api.v3.V3Updater
 import net.adoptium.api.v3.dataSources.models.AdoptRepos
@@ -33,7 +34,7 @@ class V3UpdaterTest {
     fun `adoptOpenJdk releases are copied over`() {
 
         runBlocking {
-            val repo = AdoptReposTestDataGenerator.generate();
+            val repo = AdoptReposTestDataGenerator.generate()
 
             val filter = ReleaseIncludeFilter(
                 TimeSource.now(),
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/AdoptRepositoryStub.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/AdoptRepositoryStub.kt
index 82c1bb420..b08bd2477 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/AdoptRepositoryStub.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/AdoptRepositoryStub.kt
@@ -1,6 +1,6 @@
 package net.adoptium.api.testDoubles
 
-import ReleaseIncludeFilter
+import net.adoptium.api.v3.ReleaseIncludeFilter
 import jakarta.annotation.Priority
 import jakarta.enterprise.context.ApplicationScoped
 import jakarta.enterprise.inject.Alternative
@@ -49,7 +49,7 @@ open class AdoptRepositoryStub : AdoptRepository {
         .addRelease(8, toAddSemiYoungRelease)
 
     companion object {
-        val unchangedIndex = 3
+        const val unchangedIndex = 3
 
         val toAdd = Release(
             "foo", ReleaseType.ga, "openjdk-8u", "jdk8u-2018-09-27-08-50",
diff --git a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/UpdatableVersionSupplierStub.kt b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/UpdatableVersionSupplierStub.kt
index f63238649..5e5db25c3 100644
--- a/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/UpdatableVersionSupplierStub.kt
+++ b/adoptium-updater-parent/adoptium-api-v3-updater/src/test/kotlin/net/adoptium/api/testDoubles/UpdatableVersionSupplierStub.kt
@@ -13,7 +13,7 @@ class UpdatableVersionSupplierStub : UpdatableVersionSupplier {
         // NOP
     }
 
-    override fun getTipVersion(): Int? {
+    override fun getTipVersion(): Int {
         return 15
     }
 
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/pom.xml b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/pom.xml
index d4547cc4d..7b2a7360e 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/pom.xml
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/pom.xml
@@ -56,6 +56,21 @@
             net.adoptium.api
             adoptium-api-v3-persistence
         
+        
+            org.jetbrains.kotlin
+            kotlin-stdlib-jdk8
+            ${kotlin.version}
+        
+        
+            org.jetbrains.kotlin
+            kotlin-test
+            ${kotlin.version}
+            test
+        
+        
+            jakarta.ws.rs
+            jakarta.ws.rs-api
+        
     
 
     
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdaterJsonMapper.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdaterJsonMapper.kt
index 1a6bbaa20..27afdb0da 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdaterJsonMapper.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/UpdaterJsonMapper.kt
@@ -5,11 +5,21 @@ import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.datatype.jsonp.JSONPModule
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
 import com.fasterxml.jackson.module.kotlin.KotlinModule
+import jakarta.ws.rs.Produces
+import jakarta.ws.rs.ext.Provider
 
-object UpdaterJsonMapper {
-    val mapper: ObjectMapper = ObjectMapper()
-        .setSerializationInclusion(JsonInclude.Include.NON_NULL)
-        .registerModule(KotlinModule.Builder().build())
-        .registerModule(JavaTimeModule())
-        .registerModule(JSONPModule())
+@Provider
+class UpdaterJsonMapper {
+    companion object {
+        val mapper: ObjectMapper = ObjectMapper()
+            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
+            .registerModule(KotlinModule.Builder().build())
+            .registerModule(JavaTimeModule())
+            .registerModule(JSONPModule())
+    }
+
+    @Produces
+    fun getObjectMapper(): ObjectMapper {
+        return mapper
+    }
 }
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/GitHubAuth.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/GitHubAuth.kt
index 354b9187b..c4b129b08 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/GitHubAuth.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/GitHubAuth.kt
@@ -75,7 +75,7 @@ class GitHubAuth {
             return token
         }
 
-        private suspend fun authenticateAsGitHubApp(appId: String, privateKey: String, installationId: String): GHAppInstallationToken {
+        private fun authenticateAsGitHubApp(appId: String, privateKey: String, installationId: String): GHAppInstallationToken {
             try {
                 // Remove the first and last lines
                 val sanitizedKey = privateKey
@@ -101,7 +101,7 @@ class GitHubAuth {
                     .compact()
 
                 val gitHubApp: GitHub = GitHubBuilder().withJwtToken(jwtToken).build()
-                val appInstallation: GHAppInstallation = gitHubApp.getApp().getInstallationById(installationId.toLong())
+                val appInstallation: GHAppInstallation = gitHubApp.app.getInstallationById(installationId.toLong())
                 return appInstallation.createToken().create()
             } catch (e: Exception) {
                 LOGGER.error("Error authenticating as GitHub App", e)
@@ -110,5 +110,5 @@ class GitHubAuth {
         }
     }
 
-    class FailedToAuthenticateException : Exception("Failed to authenticate to GitHub") {}
+    class FailedToAuthenticateException : Exception("Failed to authenticate to GitHub")
 }
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubInterface.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubInterface.kt
index 11ada77b3..d17f0b0e1 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubInterface.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubInterface.kt
@@ -188,7 +188,7 @@ open class GraphQLGitHubInterface @Inject constructor(
                 }
 
             } catch (e: MismatchedInputException) {
-                return null;
+                return null
             } catch (e: Exception) {
                 LOGGER.error("Query failed", e)
                 throw e
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubReleaseRequest.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubReleaseRequest.kt
index eff1d4cc1..05678ccad 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubReleaseRequest.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLGitHubReleaseRequest.kt
@@ -3,7 +3,6 @@ package net.adoptium.api.v3.dataSources.github.graphql.clients
 import com.expediagroup.graphql.client.types.GraphQLClientRequest
 import jakarta.enterprise.context.ApplicationScoped
 import jakarta.inject.Inject
-import net.adoptium.api.v3.dataSources.UpdaterHtmlClient
 import net.adoptium.api.v3.dataSources.github.graphql.models.GHAssets
 import net.adoptium.api.v3.dataSources.github.graphql.models.GHRelease
 import net.adoptium.api.v3.dataSources.github.graphql.models.PageInfo
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLRequestImpl.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLRequestImpl.kt
index ac2ea79f3..f044e55b6 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLRequestImpl.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/github/graphql/clients/GraphQLRequestImpl.kt
@@ -15,11 +15,10 @@ import java.net.URL
 open class GraphQLRequestImpl : GraphQLRequest {
 
     private val client: GraphQLKtorClient
-    private val httpClient: HttpClient
+    private val httpClient: HttpClient = HttpClient()
     val BASE_URL = "https://api.github.com/graphql"
 
     init {
-        httpClient = HttpClient()
         client = GraphQLKtorClient(
             url = URL(BASE_URL),
             httpClient = httpClient,
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/mongo/InternalDbStore.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/mongo/InternalDbStore.kt
index dc9779039..13f3f1f48 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/mongo/InternalDbStore.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-github-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/mongo/InternalDbStore.kt
@@ -1,11 +1,13 @@
 package net.adoptium.api.v3.dataSources.mongo
 
 import com.mongodb.client.model.IndexOptions
-import com.mongodb.client.model.UpdateOptions
+import com.mongodb.client.model.ReplaceOptions
+import com.mongodb.kotlin.client.coroutine.MongoCollection
 import jakarta.enterprise.context.ApplicationScoped
 import jakarta.inject.Inject
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.firstOrNull
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import net.adoptium.api.v3.dataSources.persitence.mongo.MongoClient
@@ -13,7 +15,6 @@ import net.adoptium.api.v3.dataSources.persitence.mongo.MongoInterface
 import org.bson.BsonDateTime
 import org.bson.BsonDocument
 import org.bson.Document
-import org.litote.kmongo.coroutine.CoroutineCollection
 import java.time.ZonedDateTime
 
 interface InternalDbStore {
@@ -24,27 +25,26 @@ interface InternalDbStore {
 
 @ApplicationScoped
 open class InternalDbStoreImpl @Inject constructor(mongoClient: MongoClient) : MongoInterface(), InternalDbStore {
-    private val webCache: CoroutineCollection = createCollection(mongoClient.database, "web-cache")
+    private val webCache: MongoCollection = createCollection(mongoClient.getDatabase(), "web-cache")
 
     init {
         runBlocking {
-            webCache.createIndex("""{"url":1}""", IndexOptions().background(true))
+            webCache.createIndex(Document.parse("""{"url":1}"""), IndexOptions().background(true))
         }
     }
 
     override fun putCachedWebpage(url: String, lastModified: String?, date: ZonedDateTime, data: String?): Job {
         return GlobalScope.launch {
-            webCache.updateOne(
+            webCache.replaceOne(
                 Document("url", url),
                 CacheDbEntry(url, lastModified, date, data),
-                UpdateOptions().upsert(true),
-                false
+                ReplaceOptions().upsert(true)
             )
         }
     }
 
     override suspend fun getCachedWebpage(url: String): CacheDbEntry? {
-        return webCache.findOne(Document("url", url))
+        return webCache.find(Document("url", url)).firstOrNull()
     }
 
     override suspend fun updateCheckedTime(url: String, dateTime: ZonedDateTime) {
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/pom.xml b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/pom.xml
index 5a60e7b12..026ca9380 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/pom.xml
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/pom.xml
@@ -70,6 +70,17 @@
             github-api
             1.323
         
+        
+            org.jetbrains.kotlin
+            kotlin-stdlib-jdk8
+            ${kotlin.version}
+        
+        
+            org.jetbrains.kotlin
+            kotlin-test
+            ${kotlin.version}
+            test
+        
     
 
     
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/DefaultUpdaterHtmlClient.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/DefaultUpdaterHtmlClient.kt
index 07e75b73e..9ca335361 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/DefaultUpdaterHtmlClient.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/DefaultUpdaterHtmlClient.kt
@@ -141,7 +141,7 @@ open class DefaultUpdaterHtmlClient @Inject constructor(
             try {
                 LOGGER.debug("Getting ${request.url} ${request.lastModified}")
                 val response: HttpResponse = withTimeout(REQUEST_TIMEOUT) {
-                    suspendCoroutine { continuation ->
+                    suspendCoroutine { continuation ->
                         getData(request, continuation, authInfo?.token)
                     }
                 }
diff --git a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/GitHubAuth.kt b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/GitHubAuth.kt
index c2cc24a74..0f5532943 100644
--- a/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/GitHubAuth.kt
+++ b/adoptium-updater-parent/adoptium-datasources-parent/adoptium-http-client-datasource/src/main/kotlin/net/adoptium/api/v3/dataSources/GitHubAuth.kt
@@ -73,7 +73,7 @@ class GitHubAuth {
             return token
         }
 
-        private suspend fun authenticateAsGitHubApp(appId: String, privateKey: String, installationId: String): GHAppInstallationToken {
+        private fun authenticateAsGitHubApp(appId: String, privateKey: String, installationId: String): GHAppInstallationToken {
             try {
                 // Remove the first and last lines
                 val sanitizedKey = privateKey
@@ -99,7 +99,7 @@ class GitHubAuth {
                     .compact()
 
                 val gitHubApp: GitHub = GitHubBuilder().withJwtToken(jwtToken).build()
-                val appInstallation: GHAppInstallation = gitHubApp.getApp().getInstallationById(installationId.toLong())
+                val appInstallation: GHAppInstallation = gitHubApp.app.getInstallationById(installationId.toLong())
                 return appInstallation.createToken().create()
             } catch (e: Exception) {
                 LOGGER.error("Error authenticating as GitHub App", e)
@@ -108,5 +108,5 @@ class GitHubAuth {
         }
     }
 
-    class FailedToAuthenticateException : Exception("Failed to authenticate as GitHub App") {}
+    class FailedToAuthenticateException : Exception("Failed to authenticate as GitHub App")
 }
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/pom.xml b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/pom.xml
index 0cf0cc5c1..2e63a2388 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/pom.xml
+++ b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/pom.xml
@@ -22,11 +22,21 @@
             adoptium-github-datasource
             ${project.version}
         
+        
+            org.jetbrains.kotlin
+            kotlin-stdlib-jdk8
+            ${kotlin.version}
+        
+        
+            org.jetbrains.kotlin
+            kotlin-test
+            ${kotlin.version}
+            test
+        
     
 
     
         src/main/kotlin
-        src/test/kotlin
     
 
 
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptBinaryMapper.kt b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptBinaryMapper.kt
index adcac54d4..ab9dafe71 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptBinaryMapper.kt
+++ b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptBinaryMapper.kt
@@ -28,12 +28,13 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
 
     companion object {
         @JvmStatic
-        private val LOGGER = LoggerFactory.getLogger(this::class.java)
+        private val LOGGER = LoggerFactory.getLogger(AdoptBinaryMapper::class.java)
         private const val HOTSPOT_JFR = "hotspot-jfr"
         private const val TEMURIN = "temurin"
+
+        private val EXCLUDED = listOf("corretto")
     }
 
-    private val EXCLUDED = listOf("corretto")
 
     suspend fun toBinaryList(ghBinaryAssets: List, allGhAssets: List, ghAssetsWithMetadata: Map): List {
         // probably whitelist rather than black list
@@ -55,9 +56,9 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
 
                 val binaryMetadata = ghAssetsWithMetadata[ghBinaryAsset]
 
-                val heapSize = getEnumFromFileName(ghBinaryAsset.name, HeapSize.values(), HeapSize.normal)
+                val heapSize = getEnumFromFileName(ghBinaryAsset.name, HeapSize.entries.toTypedArray(), HeapSize.normal)
 
-                val cLib = getEnumFromFileNameNullable(ghBinaryAsset.name, CLib.values(), null)
+                val cLib = getEnumFromFileNameNullable(ghBinaryAsset.name, CLib.entries.toTypedArray(), null)
 
                 val installer = getInstaller(ghBinaryAsset, allGhAssets)
                 val `package` = getPackage(allGhAssets, ghBinaryAsset, binaryMetadata)
@@ -90,13 +91,13 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
         val binarySize = binaryAsset.size
         val binaryChecksumLink = getCheckSumLink(fullAssetList, binaryName)
         val signatureLink = getSignatureLink(fullAssetList, binaryAsset.name)
-        val binaryChecksum: String?
 
-        binaryChecksum = if (binaryMetadata != null && binaryMetadata.sha256.isNotEmpty()) {
-            binaryMetadata.sha256
-        } else {
-            getChecksum(binaryChecksumLink)
-        }
+        val binaryChecksum: String? =
+            if (binaryMetadata != null && binaryMetadata.sha256.isNotEmpty()) {
+                binaryMetadata.sha256
+            } else {
+                getChecksum(binaryChecksumLink)
+            }
 
         val metadataLink = getMetadataLink(fullAssetList, binaryName)
 
@@ -115,7 +116,7 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
     private suspend fun getInstaller(binaryAsset: GHAsset, fullAssetList: List): Installer? {
 
         val nameWithoutExtension =
-            BINARY_ASSET_WHITELIST.fold(binaryAsset.name, { assetName, extension -> assetName.replace(extension, "") })
+            BINARY_ASSET_WHITELIST.fold(binaryAsset.name) { assetName, extension -> assetName.replace(extension, "") }
 
         val installer = fullAssetList
             .filter { it.name.startsWith(nameWithoutExtension) }
@@ -171,10 +172,10 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
     }
 
     private fun removeExtensionFromName(binary_name: String): String {
-        return BINARY_ASSET_WHITELIST.foldRight(binary_name, { extension, name -> name.removeSuffix(extension) })
+        return BINARY_ASSET_WHITELIST.foldRight(binary_name) { extension, name -> name.removeSuffix(extension) }
     }
 
-    private fun isBinaryAsset(asset: GHAsset) = ARCHIVE_WHITELIST.any { asset.name.endsWith(it) } || ( asset.name.endsWith(".json") && asset.name.contains("-sbom_") )
+    private fun isBinaryAsset(asset: GHAsset) = ARCHIVE_WHITELIST.any { asset.name.endsWith(it) } || (asset.name.endsWith(".json") && asset.name.contains("-sbom_"))
 
     private fun binaryFromName(
         asset: GHAsset,
@@ -186,11 +187,11 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
         cLib: CLib?
     ): Binary {
         val scmRef = null
-        val os = getEnumFromFileName(asset.name, OperatingSystem.values())
-        val architecture = getEnumFromFileName(asset.name, Architecture.values())
-        val binaryType = getEnumFromFileName(asset.name, ImageType.values(), ImageType.jdk)
-        val jvmImpl = getEnumFromFileName(asset.name, JvmImpl.values(), JvmImpl.hotspot)
-        val project = getEnumFromFileName(asset.name, Project.values(), Project.jdk)
+        val os = getEnumFromFileName(asset.name, OperatingSystem.entries.toTypedArray())
+        val architecture = getEnumFromFileName(asset.name, Architecture.entries.toTypedArray())
+        val binaryType = getEnumFromFileName(asset.name, ImageType.entries.toTypedArray(), ImageType.jdk)
+        val jvmImpl = getEnumFromFileName(asset.name, JvmImpl.entries.toTypedArray(), JvmImpl.hotspot)
+        val project = getEnumFromFileName(asset.name, Project.entries.toTypedArray(), Project.jdk)
 
         return Binary(
             pack,
@@ -242,7 +243,7 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
 
     private fun getImageType(asset: GHAsset, binaryMetadata: GHMetaData): ImageType {
         // static-libs incorrectly labeled as JDK, if the name tells us it's a static-lib, trust that over the metadata file
-        val binaryTypeFromName = getEnumFromFileName(asset.name, ImageType.values(), ImageType.jdk)
+        val binaryTypeFromName = getEnumFromFileName(asset.name, ImageType.entries.toTypedArray(), ImageType.jdk)
         return if (binaryTypeFromName == ImageType.staticlibs) {
             ImageType.staticlibs
         } else {
@@ -271,7 +272,7 @@ class AdoptBinaryMapper @Inject constructor(private val gitHubHtmlClient: GitHub
 
     private suspend fun getChecksum(binary_checksum_link: String?): String? {
         try {
-            if (!(binary_checksum_link == null || binary_checksum_link.isEmpty())) {
+            if (!binary_checksum_link.isNullOrEmpty()) {
                 LOGGER.debug("Pulling checksum for $binary_checksum_link")
                 val checksum = gitHubHtmlClient.getUrl(binary_checksum_link)
                 if (checksum != null) {
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptReleaseMapper.kt b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptReleaseMapper.kt
index 6fa176ad8..036198742 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptReleaseMapper.kt
+++ b/adoptium-updater-parent/adoptium-mappers-parent/adopt-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/adopt/AdoptReleaseMapper.kt
@@ -1,7 +1,7 @@
 package net.adoptium.api.v3.mapping.adopt
 
 import jakarta.enterprise.context.ApplicationScoped
-import jakarta.enterprise.inject.Model
+import jakarta.inject.Inject
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 import net.adoptium.api.v3.ReleaseResult
@@ -29,8 +29,6 @@ import java.security.MessageDigest
 import java.time.ZonedDateTime
 import java.util.*
 import java.util.regex.Pattern
-import jakarta.inject.Inject
-import jakarta.inject.Singleton
 
 @ApplicationScoped
 open class AdoptReleaseMapperFactory @Inject constructor(
@@ -50,7 +48,7 @@ open class AdoptReleaseMapperFactory @Inject constructor(
     }
 }
 
-private class AdoptReleaseMapper constructor(
+private class AdoptReleaseMapper(
     val adoptBinaryMapper: AdoptBinaryMapper,
     val htmlClient: GitHubHtmlClient,
     val vendor: Vendor
@@ -196,7 +194,7 @@ private class AdoptReleaseMapper constructor(
             .filter { asset ->
                 BinaryMapper.BINARY_EXTENSIONS.any { asset.name.endsWith(it) }
             }
-            .map { it.downloadCount }.sum()
+            .sumOf { it.downloadCount }
 
         return Release(
             id,
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/mappers-common/pom.xml b/adoptium-updater-parent/adoptium-mappers-parent/mappers-common/pom.xml
index a417251cf..7e38b04d3 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/mappers-common/pom.xml
+++ b/adoptium-updater-parent/adoptium-mappers-parent/mappers-common/pom.xml
@@ -25,6 +25,17 @@
             net.adoptium.api
             adoptium-api-v3-persistence
         
+        
+            org.jetbrains.kotlin
+            kotlin-stdlib-jdk8
+            ${kotlin.version}
+        
+        
+            org.jetbrains.kotlin
+            kotlin-test
+            ${kotlin.version}
+            test
+        
     
 
     
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/pom.xml b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/pom.xml
index 2f37b8434..947da21dd 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/pom.xml
+++ b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/pom.xml
@@ -22,11 +22,21 @@
             adoptium-github-datasource
             ${project.version}
         
+        
+            org.jetbrains.kotlin
+            kotlin-stdlib-jdk8
+            ${kotlin.version}
+        
+        
+            org.jetbrains.kotlin
+            kotlin-test
+            ${kotlin.version}
+            test
+        
     
 
     
         src/main/kotlin
-        src/test/kotlin
     
 
 
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamBinaryMapper.kt b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamBinaryMapper.kt
index e86868d2e..b7f427dcc 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamBinaryMapper.kt
+++ b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamBinaryMapper.kt
@@ -39,11 +39,11 @@ object UpstreamBinaryMapper : BinaryMapper() {
                 val signatureLink = getSignatureLink(assets, asset.name)
                 val pack = Package(asset.name, asset.downloadUrl, asset.size, null, null, asset.downloadCount, signatureLink, null)
 
-                val os = getEnumFromFileName(asset.name, OperatingSystem.values())
-                val architecture = getEnumFromFileName(asset.name, Architecture.values())
-                val imageType = getEnumFromFileName(asset.name, ImageType.values(), ImageType.jdk)
+                val os = getEnumFromFileName(asset.name, OperatingSystem.entries.toTypedArray())
+                val architecture = getEnumFromFileName(asset.name, Architecture.entries.toTypedArray())
+                val imageType = getEnumFromFileName(asset.name, ImageType.entries.toTypedArray(), ImageType.jdk)
                 val updatedAt = getUpdatedTime(asset)
-                val projectType = getEnumFromFileName(asset.name, Project.values(), Project.jdk)
+                val projectType = getEnumFromFileName(asset.name, Project.entries.toTypedArray(), Project.jdk)
 
                 Binary(
                     pack,
diff --git a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamReleaseMapper.kt b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamReleaseMapper.kt
index cc44380b8..77ce74687 100644
--- a/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamReleaseMapper.kt
+++ b/adoptium-updater-parent/adoptium-mappers-parent/upstream-mappers/src/main/kotlin/net/adoptium/api/v3/mapping/upstream/UpstreamReleaseMapper.kt
@@ -31,7 +31,7 @@ object UpstreamReleaseMapper : ReleaseMapper() {
             .filter { asset ->
                 BinaryMapper.BINARY_EXTENSIONS.any { asset.name.endsWith(it) }
             }
-            .map { it.downloadCount }.sum()
+            .sumOf { it.downloadCount }
 
         val vendor = Vendor.openjdk
 
diff --git a/pom.xml b/pom.xml
index cb7010c73..24fb632b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
 
     
     
-        3.9.6
+        3.9.8
     
 
     
@@ -19,7 +19,7 @@
         0.8.12
         17
         17
-        1.9.23
+        2.0.10
         3.1.0
         3.7.1
         3.5.0
@@ -82,7 +82,7 @@
         4.7.3
         UTF-8
         UTF-8
-        3.13.0
+        3.13.2