Skip to content

Commit

Permalink
✨ Display scripts executions by environments
Browse files Browse the repository at this point in the history
  • Loading branch information
Lysoun committed Aug 6, 2024
1 parent 11e602a commit 637479e
Show file tree
Hide file tree
Showing 25 changed files with 396 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ val batchExecutionService = BatchExecutionService(batchExecutionDao)
val batchExecutionGrpcServiceImpl = BatchExecutionGrpcServiceImpl(batchExecutionService = batchExecutionService)

val scriptExecutionDao = ScriptExecutionDao(dslContext)
val scriptExecutionService = ScriptExecutionService(scriptExecutionDao)
val scriptExecutionService = ScriptExecutionService(scriptExecutionDao, environmentService)
val scriptExecutionGrpcServiceImpl = ScriptExecutionGrpcServiceImpl(scriptExecutionService)

val moduleEnvironmentTokenDao = ModuleEnvironmentTokenDao(dslContext)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package dao.execution.script

import dao.utils.toDto
import dao.utils.toOffsetDateTime
import dao.utils.*
import execution.INITIAL_STATUS
import execution.Status
import execution.script.*
import generated.domain.enums.ExecutionStatus
import generated.domain.tables.references.DM_BATCH_EXECUTION
import generated.domain.tables.references.DM_SCRIPT
import generated.domain.tables.references.DM_SCRIPT_EXECUTION
import org.jooq.Condition
import org.jooq.DSLContext
import org.jooq.impl.DSL
import org.jooq.impl.DSL.`val`
import org.jooq.impl.DSL.*
import script.Script
import java.sql.ResultSet
import java.util.*

class ScriptExecutionDao(val dslContext: DSLContext): ScriptExecutionDaoInterface {
Expand Down Expand Up @@ -96,6 +98,67 @@ class ScriptExecutionDao(val dslContext: DSLContext): ScriptExecutionDaoInterfac
.from(DM_SCRIPT_EXECUTION.join(DM_SCRIPT).on(DM_SCRIPT.CHECKSUM.eq(DM_SCRIPT_EXECUTION.FK_SCRIPT_REF)))
.where(searchRequest.toCondition())
.fetchInto(ScriptExecutionListItem::class.java)

override fun findModuleScriptsExecutionsInformation(moduleRef: UUID): List<ScriptWithAllExecutions> {
val resultSet = dslContext.select(
DM_SCRIPT.CHECKSUM,
DM_SCRIPT.NAME,
DM_SCRIPT.CONTENT,
DM_SCRIPT_EXECUTION.ID,
DM_SCRIPT_EXECUTION.START_DATE,
DM_SCRIPT_EXECUTION.END_DATE,
DM_SCRIPT_EXECUTION.DURATION_IN_MS,
DM_SCRIPT_EXECUTION.EXECUTION_ORDER_INDEX,
DM_SCRIPT_EXECUTION.OUTPUT,
DM_SCRIPT_EXECUTION.STATUS,
DM_BATCH_EXECUTION.FK_ENVIRONMENT_REF,
).from(
DM_SCRIPT_EXECUTION
.join(DM_BATCH_EXECUTION.where(DM_BATCH_EXECUTION.FK_MODULE_REF.eq(moduleRef))).on(
DM_BATCH_EXECUTION.ID.eq(DM_SCRIPT_EXECUTION.FK_BATCH_EXECUTION_REF)
)
.join(DM_SCRIPT).on(DM_SCRIPT.CHECKSUM.eq(DM_SCRIPT_EXECUTION.FK_SCRIPT_REF))
)
.orderBy(DM_SCRIPT.CHECKSUM)
.fetchResultSet()

val scriptsWithAllExecutions = mutableListOf<ScriptWithAllExecutions>()
var currentScript: Script? = null
var currentScriptExecutions: MutableList<ScriptExecutionWithEnvironment> = mutableListOf()
while(resultSet.next()) {
val checksum = resultSet.getString(DM_SCRIPT.CHECKSUM.name)

if (checksum != currentScript?.checksum) {
if (currentScript != null) {
scriptsWithAllExecutions.add(
ScriptWithAllExecutions(
currentScript,
currentScriptExecutions
)
)
}

currentScript = Script(
name = resultSet.getString(DM_SCRIPT.NAME.name),
checksum = checksum,
content = resultSet.getString(DM_SCRIPT.CONTENT.name),
)
currentScriptExecutions = mutableListOf()
}
currentScriptExecutions.add(resultSet.toScriptExecutionWithModule())
}

if (currentScript != null) {
scriptsWithAllExecutions.add(
ScriptWithAllExecutions(
currentScript,
currentScriptExecutions
)
)
}

return scriptsWithAllExecutions
}
}

fun ScriptExecutionSearchRequest.toCondition(): Condition {
Expand All @@ -110,4 +173,14 @@ fun ScriptExecutionSearchRequest.toCondition(): Condition {
}

return condition
}
}

fun ResultSet.toScriptExecutionWithModule(): ScriptExecutionWithEnvironment = ScriptExecutionWithEnvironment(
id = this.getUUID(DM_SCRIPT_EXECUTION.ID.name),
startDate = this.getOffsetDateTime(DM_SCRIPT_EXECUTION.START_DATE.name),
durationInMs = this.getIntOrNull(DM_SCRIPT_EXECUTION.DURATION_IN_MS.name),
executionOrderIndex = this.getInt(DM_SCRIPT_EXECUTION.EXECUTION_ORDER_INDEX.name),
output = this.getString(DM_SCRIPT_EXECUTION.OUTPUT.name),
status = Status.valueOf(this.getString(DM_SCRIPT_EXECUTION.STATUS.name)),
fkEnvironmentRef = this.getUUID(DM_BATCH_EXECUTION.FK_ENVIRONMENT_REF.name),
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import execution.batch.Type
import generated.domain.enums.BatchExecutionOrigin
import generated.domain.enums.BatchExecutionType
import generated.domain.enums.ExecutionStatus
import java.sql.ResultSet
import java.time.Instant
import java.time.OffsetDateTime
import java.time.ZoneId
import java.util.*

fun Origin.toDto(): BatchExecutionOrigin =
when (this) {
Expand Down Expand Up @@ -40,4 +42,17 @@ fun Status.toDto(): ExecutionStatus =
*/
fun Instant.toOffsetDateTime(): OffsetDateTime {
return OffsetDateTime.ofInstant(this, ZoneId.of("UTC").normalized())
}


fun ResultSet.getOffsetDateTime(key: String): OffsetDateTime? {
val date = this.getTimestamp(key) ?: return null

return date.toInstant().toOffsetDateTime()
}

fun ResultSet.getUUID(key: String): UUID = UUID.fromString(this.getString(key))

fun ResultSet.getIntOrNull(name: String): Int? {
return this.getString(name)?.toInt()
}
12 changes: 12 additions & 0 deletions modules/app-server/dao/src/test/kotlin/UtilsRandom.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import kotlin.random.Random

private val charactersAvailableForRandom = listOf(
'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z'
)

fun randomString(length: Int = 10): String {
return (1..length)
.map { Random.nextInt(0, charactersAvailableForRandom.size).let { charactersAvailableForRandom[it] } }
.joinToString("")
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import execution.batch.BatchExecutionEndUpdateRequest
import execution.batch.BatchExecutionSearchRequest
import generated.domain.tables.pojos.DmBatchExecution
import generated.domain.tables.references.DM_BATCH_EXECUTION
import generated.domain.tables.references.DM_ENVIRONMENT
import generated.domain.tables.references.DM_PROJECT
import module.Module
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Nested
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
package dao.execution.script

import AbstractDaoTest
import dao.execution.batch.BatchExecutionDao
import dao.execution.batch.buildBatchExecutionCreationRequest
import dao.environment.EnvironmentDao
import dao.environment.buildEnvironmentCreationRequest
import dao.module.ModuleDao
import dao.execution.batch.buildBatchExecutionCreationRequest
import dao.module.buildModuleCreationRequest
import dao.project.ProjectDao
import dao.project.buildProjectCreationRequest
import dao.script.ScriptDao
import dao.script.buildScriptCreationRequest
import dao.utils.toDto
import execution.INITIAL_STATUS
import execution.Status
import execution.script.ScriptExecutionSearchRequest
import execution.script.ScriptExecutionWithEnvironment
import generated.domain.tables.pojos.DmScriptExecution
import generated.domain.tables.references.DM_SCRIPT_EXECUTION
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import script.Script
import execution.script.ScriptExecutionSearchRequest
import strikt.api.expectThat
import strikt.assertions.*
import java.time.OffsetDateTime
Expand All @@ -39,14 +35,15 @@ internal class ScriptExecutionDaoTest : AbstractDaoTest() {
private lateinit var batchExecutionRef1: UUID
private lateinit var batchExecutionRef2: UUID
private lateinit var projectId: UUID
private lateinit var environmentId: UUID
private lateinit var moduleId: UUID
private lateinit var script1: Script

@BeforeAll
@JvmStatic
fun insertNeededObjectsInDB() {
projectId = projectDao.insert(buildProjectCreationRequest()).id
val environmentId = environmentDao.insert(buildEnvironmentCreationRequest(fkProjectRef = projectId)).id
environmentId = environmentDao.insert(buildEnvironmentCreationRequest(fkProjectRef = projectId)).id
moduleId = moduleDao.insert(buildModuleCreationRequest(fkProjectRef = projectId)).id
batchExecutionRef1 = batchExecutionDao.insert(
buildBatchExecutionCreationRequest(
Expand Down Expand Up @@ -587,4 +584,114 @@ internal class ScriptExecutionDaoTest : AbstractDaoTest() {
}
}

@Nested
inner class TestFindModuleScriptsExecutionsInformation {
@Test
fun `load all scripts executed at least once on any environment`() {
// Given
val environment1 = environmentDao.insert(buildEnvironmentCreationRequest(fkProjectRef = projectId))
val environment2 = environmentDao.insert(buildEnvironmentCreationRequest(fkProjectRef = projectId))

val script1 = scriptDao.insert(buildScriptCreationRequest())
val script2 = scriptDao.insert(buildScriptCreationRequest())

val batchExecution1 = batchExecutionDao.insert(
buildBatchExecutionCreationRequest(
fkEnvironmentRef = environment1.id,
fkModuleRef = moduleId
)
)

val batchExecution2 = batchExecutionDao.insert(
buildBatchExecutionCreationRequest(
fkEnvironmentRef = environment2.id,
fkModuleRef = moduleId
)
)
scriptExecutionDao.insert(
buildScriptExecutionCreationRequest(
batchExecutionRef = batchExecution1.id,
scriptRef = script1.checksum
)
)
scriptExecutionDao.insert(
buildScriptExecutionCreationRequest(
batchExecutionRef = batchExecution2.id,
scriptRef = script2.checksum
)
)

// When
val moduleScriptsExecutionsInformation = scriptExecutionDao.findModuleScriptsExecutionsInformation(
moduleRef = moduleId
)

// Then
expectThat(moduleScriptsExecutionsInformation).map { it.script }
.containsExactlyInAnyOrder(
script1,
script2
)
}

@Test
fun `load all executions of one script`() {
// Given
val script1 = scriptDao.insert(buildScriptCreationRequest())

val batchExecution1 = batchExecutionDao.insert(
buildBatchExecutionCreationRequest(
fkEnvironmentRef = environmentId,
fkModuleRef = moduleId
)
)

val batchExecution2 = batchExecutionDao.insert(
buildBatchExecutionCreationRequest(
fkEnvironmentRef = environmentId,
fkModuleRef = moduleId
)
)

val scriptExecution1 = scriptExecutionDao.insert(
buildScriptExecutionCreationRequest(
batchExecutionRef = batchExecution1.id,
scriptRef = script1.checksum
)
)
val scriptExecution2 = scriptExecutionDao.insert(
buildScriptExecutionCreationRequest(
batchExecutionRef = batchExecution2.id,
scriptRef = script1.checksum
)
)

// When
val moduleScriptsExecutionsInformation = scriptExecutionDao.findModuleScriptsExecutionsInformation(
moduleRef = moduleId
)

// Then
expectThat(moduleScriptsExecutionsInformation)[0].get { executions }.containsExactlyInAnyOrder(
ScriptExecutionWithEnvironment(
id = scriptExecution1.id,
startDate = scriptExecution1.startDate,
durationInMs = scriptExecution1.durationInMs,
executionOrderIndex = scriptExecution1.executionOrderIndex,
output = scriptExecution1.output,
status = scriptExecution1.status,
fkEnvironmentRef = environmentId
),
ScriptExecutionWithEnvironment(
id = scriptExecution2.id,
startDate = scriptExecution2.startDate,
durationInMs = scriptExecution2.durationInMs,
executionOrderIndex = scriptExecution2.executionOrderIndex,
output = scriptExecution2.output,
status = scriptExecution2.status,
fkEnvironmentRef = environmentId
)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package dao.script

import randomString
import script.ScriptCreationRequest

fun buildScriptCreationRequest(
name: String = "myName",
checksum: String = "checksum",
content: String = "content"
name: String = randomString(),
checksum: String = randomString(),
content: String = randomString()
) = ScriptCreationRequest(name = name, checksum = checksum, content = content)
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package execution.script

import environment.Environment
import execution.Status
import script.Script
import java.time.OffsetDateTime
import java.util.*

data class ModuleScriptsExecutionsInformation(
val scriptsWithAllExecutions: List<ScriptWithAllExecutions>,
val environments: List<Environment>
)

data class ScriptExecutionWithEnvironment(
val id: UUID,
val startDate: OffsetDateTime?,
val durationInMs: Int?,
val executionOrderIndex: Int,
val output: String?,
val status: Status?,
val fkEnvironmentRef: UUID
)

data class ScriptWithAllExecutions(
val script: Script,
val executions: List<ScriptExecutionWithEnvironment>
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ interface ScriptExecutionDaoInterface {
fun findOneById(id: UUID): ScriptExecution?
fun findOneDetailById(id: UUID): ScriptExecutionDetail?
fun find(searchRequest: ScriptExecutionSearchRequest): List<ScriptExecutionListItem>
fun findModuleScriptsExecutionsInformation(moduleRef: UUID): List<ScriptWithAllExecutions>
}
Loading

0 comments on commit 637479e

Please sign in to comment.