Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
422 changes: 373 additions & 49 deletions admin-app/src/main/resources/openapi.yml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ val TestDetails.definitionId: String
}

suspend fun HttpClient.putBuild(payload: BuildPayload): HttpResponse {
return put("/data-ingest/builds") {
return put("/data-ingest/builds/info") {
setBody(payload)
}.assertSuccessStatus()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class Build(
val appId: String,
val commitSha: String?,
val buildVersion: String?,
val branch: String?,
val instanceId: String?,
val commitDate: LocalDateTime?,
val commitMessage: String?,
val commitAuthor: String?
val branch: String? = null,
val commitDate: LocalDateTime? = null,
val commitMessage: String? = null,
val commitAuthor: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import com.epam.drill.admin.writer.rawdata.entity.Build
import java.time.LocalDate

interface BuildRepository {
suspend fun create(build: Build)
suspend fun saveBuildInfo(build: Build)
suspend fun saveBuildId(build: Build)
suspend fun existsById(groupId: String, appId: String, buildId: String): Boolean
suspend fun deleteAllCreatedBefore(groupId: String, createdBefore: LocalDate)
suspend fun deleteByBuildId(groupId: String, appId: String, buildId: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ import org.jetbrains.exposed.sql.upsert
import java.time.LocalDate

class BuildRepositoryImpl: BuildRepository {
override suspend fun create(build: Build) {
override suspend fun saveBuildInfo(build: Build) {
BuildTable.upsert(
onUpdateExclude = listOf(BuildTable.createdAt),
onUpdateExclude = listOf(
BuildTable.createdAt,
),
) {
it[id] = build.id
it[groupId] = build.groupId
Expand All @@ -44,6 +46,27 @@ class BuildRepositoryImpl: BuildRepository {
it[updatedAt] = org.jetbrains.exposed.sql.javatime.CurrentDateTime
}
}

override suspend fun saveBuildId(build: Build) {
BuildTable.upsert(
onUpdateExclude = listOf(
BuildTable.createdAt,
BuildTable.branch,
BuildTable.committedAt,
BuildTable.commitAuthor,
BuildTable.commitMessage
),
) {
it[id] = build.id
it[groupId] = build.groupId
it[appId] = build.appId
it[commitSha] = build.commitSha
it[buildVersion] = build.buildVersion
it[instanceId] = build.instanceId
it[updatedAt] = org.jetbrains.exposed.sql.javatime.CurrentDateTime
}
}

override suspend fun existsById(groupId: String, appId: String, buildId: String): Boolean {
return BuildTable.selectAll().where {
(BuildTable.groupId eq groupId) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ private val logger = KotlinLogging.logger {}
@Resource("builds")
class BuildsRoute()

@Resource("builds/info")
class BuildsInfoRoute()

@Resource("instances")
class InstancesRoute()

Expand Down Expand Up @@ -81,6 +84,7 @@ class MethodIgnoreRulesRoute() {
fun Route.dataIngestRoutes() {
route("/data-ingest") {
putBuilds()
putBuildsInfo()
putInstances()
postCoverage()
putMethods()
Expand All @@ -104,6 +108,15 @@ fun Route.putBuilds() {
}
}

fun Route.putBuildsInfo() {
val rawDataWriter by closestDI().instance<RawDataWriter>()

put<BuildsInfoRoute> {
rawDataWriter.saveBuildInfo(call.decompressAndReceive())
call.ok("Build info saved")
}
}

fun Route.putInstances() {
val rawDataWriter by closestDI().instance<RawDataWriter>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.epam.drill.admin.writer.rawdata.views.MethodIgnoreRuleView

interface RawDataWriter {
suspend fun saveBuild(buildPayload: BuildPayload)
suspend fun saveBuildInfo(buildPayload: BuildPayload)
suspend fun saveInstance(instancePayload: InstancePayload)
suspend fun saveMethods(methodsPayload: MethodsPayload)
suspend fun saveCoverage(coveragePayload: CoveragePayload)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ class RawDataServiceImpl(
) : RawDataWriter {

override suspend fun saveBuild(buildPayload: BuildPayload) {
val build = Build(
id = generateBuildId(
buildPayload.groupId,
buildPayload.appId,
"",
buildPayload.commitSha,
buildPayload.buildVersion
),
groupId = buildPayload.groupId,
appId = buildPayload.appId,
instanceId = null,
commitSha = buildPayload.commitSha,
buildVersion = buildPayload.buildVersion,
)
transaction {
buildRepository.saveBuildId(build)
}
}

override suspend fun saveBuildInfo(buildPayload: BuildPayload) {
val build = Build(
id = generateBuildId(
buildPayload.groupId,
Expand All @@ -66,7 +86,7 @@ class RawDataServiceImpl(
commitAuthor = buildPayload.commitAuthor
)
transaction {
buildRepository.create(build)
buildRepository.saveBuildInfo(build)
}
}

Expand Down Expand Up @@ -94,12 +114,8 @@ class RawDataServiceImpl(
instanceId = instancePayload.instanceId,
commitSha = instancePayload.commitSha,
buildVersion = instancePayload.buildVersion,
branch = null,
commitDate = null,
commitMessage = null,
commitAuthor = null
)
buildRepository.create(build)
buildRepository.saveBuildId(build)
}
instanceRepository.create(instance)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.epam.drill.admin.writer.rawdata

import com.epam.drill.admin.writer.rawdata.route.putBuilds
import com.epam.drill.admin.writer.rawdata.route.putBuildsInfo
import com.epam.drill.admin.writer.rawdata.table.BuildTable
import com.epam.drill.admin.test.*
import com.epam.drill.admin.writer.rawdata.config.RawDataWriterDatabaseConfig
Expand All @@ -28,6 +29,7 @@ import java.time.LocalDateTime
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

class BuildsApiTest : DatabaseTests({ RawDataWriterDatabaseConfig.init(it) }) {
Expand All @@ -50,8 +52,56 @@ class BuildsApiTest : DatabaseTests({ RawDataWriterDatabaseConfig.init(it) }) {
"groupId": "$testGroup",
"appId": "$testApp",
"buildVersion": "$testBuildVersion",
"commitSha": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
}
""".trimIndent()
)
}.apply {
assertEquals(HttpStatusCode.OK, status)
assertJsonEquals(
"""
{
"message": "Build saved"
}
""".trimIndent(), bodyAsText()
)
}

val savedBuilds = BuildTable.selectAll()
.filter { it[BuildTable.groupId] == testGroup }
.filter { it[BuildTable.appId] == testApp }
.filter { it[BuildTable.buildVersion] == testBuildVersion }
assertEquals(1, savedBuilds.size)
savedBuilds.forEach {
assertNull(it[BuildTable.branch])
assertNotNull(it[BuildTable.commitSha])
assertNull(it[BuildTable.commitAuthor])
assertNull(it[BuildTable.commitMessage])
assertNull(it[BuildTable.committedAt])
assertTrue(it[BuildTable.createdAt] >= timeBeforeTest)
}
}

@Test
fun `given new build, put builds info should create new build with info fields and return OK`() = withRollback {
val testGroup = "test-group"
val testApp = "test-app"
val testBuildVersion = "2.0.0"
val timeBeforeTest = LocalDateTime.now()
val app = drillApplication(rawDataServicesDIModule) {
putBuildsInfo()
}

app.client.put("/builds/info") {
header(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(
"""
{
"groupId": "$testGroup",
"appId": "$testApp",
"buildVersion": "$testBuildVersion",
"commitSha": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"branch": "main",
"commitSha": "d3516472fd72cd0f9ccb7a1dc4b5e7b80a014fd2",
"commitMessage": "Initial commit",
"commitDate": "Thu Feb 27 10:06:24 2025 +0100",
"commitAuthor": "John Doe"
Expand All @@ -63,7 +113,7 @@ class BuildsApiTest : DatabaseTests({ RawDataWriterDatabaseConfig.init(it) }) {
assertJsonEquals(
"""
{
"message": "Build saved"
"message": "Build info saved"
}
""".trimIndent(), bodyAsText()
)
Expand All @@ -75,12 +125,69 @@ class BuildsApiTest : DatabaseTests({ RawDataWriterDatabaseConfig.init(it) }) {
.filter { it[BuildTable.buildVersion] == testBuildVersion }
assertEquals(1, savedBuilds.size)
savedBuilds.forEach {
assertNotNull(it[BuildTable.branch])
assertEquals("main", it[BuildTable.branch])
assertNotNull(it[BuildTable.commitSha])
assertEquals("John Doe", it[BuildTable.commitAuthor])
assertEquals("Initial commit", it[BuildTable.commitMessage])
assertNotNull(it[BuildTable.committedAt])
assertTrue(it[BuildTable.createdAt] >= timeBeforeTest)
}
}

@Test
fun `given existing build info, put builds should not update info fields and return OK`() = withRollback {
val testGroup = "test-group"
val testApp = "test-app"
val testBuildVersion = "3.0.0"
val testCommitSha = "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"
val app = drillApplication(rawDataServicesDIModule) {
putBuildsInfo()
putBuilds()
}
app.client.put("/builds/info") {
header(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(
"""
{
"groupId": "$testGroup",
"appId": "$testApp",
"buildVersion": "$testBuildVersion",
"commitSha": "$testCommitSha",
"branch": "develop",
"commitMessage": "Feature commit",
"commitDate": "Thu Feb 27 10:06:24 2025 +0100",
"commitAuthor": "Jane Doe"
}
""".trimIndent()
)
}

app.client.put("/builds") {
header(HttpHeaders.ContentType, ContentType.Application.Json.toString())
setBody(
"""
{
"groupId": "$testGroup",
"appId": "$testApp",
"buildVersion": "$testBuildVersion",
"commitSha": "$testCommitSha"
}
""".trimIndent()
)
}.apply {
assertEquals(HttpStatusCode.OK, status)
}

val buildsBeforeInfo = BuildTable.selectAll()
.filter { it[BuildTable.groupId] == testGroup }
.filter { it[BuildTable.appId] == testApp }
.filter { it[BuildTable.buildVersion] == testBuildVersion }
assertEquals(1, buildsBeforeInfo.size)
buildsBeforeInfo.forEach {
assertNotNull(it[BuildTable.branch])
assertNotNull(it[BuildTable.commitAuthor])
assertNotNull(it[BuildTable.commitMessage])
assertNotNull(it[BuildTable.committedAt])
assertTrue(it[BuildTable.createdAt] >= timeBeforeTest)
}
}

Expand Down
Loading