diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/Repository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/Repository.kt index 7fca29112aeb65d690cc15d46768be5549289fe9..fb409de39884cd3ec58f0a4f13d1c09b04502750 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/Repository.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/Repository.kt @@ -14,7 +14,7 @@ class Repository { var id: UUID? = null @OrderBy("time_stamp DESC") - @OneToMany(mappedBy = "repository", cascade = [CascadeType.ALL]) + @OneToMany(mappedBy = "repository", cascade = [CascadeType.ALL], orphanRemoval = true) var toolRuns: MutableList<ToolRun> = mutableListOf() @Column(name = "name") @@ -29,4 +29,15 @@ class Repository { @Column(name = "url") var url: String? = null + + fun addToolResults(toolRuns: Collection<ToolRun>) { + toolRuns.forEach { + this.addToolResult(it) + } + } + + fun addToolResult(toolRun: ToolRun) { + toolRuns.add(toolRun) + toolRun.repository = this + } } \ No newline at end of file diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/sarif/SarifExtensions.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/sarif/SarifExtensions.kt index f2d61e37f5e07a70dc98d269fa47b68a76a907f5..74ec79f60a10cc7319437b26ad8cd12eba4511c5 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/sarif/SarifExtensions.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/sarif/SarifExtensions.kt @@ -13,7 +13,7 @@ import java.util.* fun de.fraunhofer.iem.dataprovider.sarif.Rule.asDbObject(): de.fraunhofer.iem.dataprovider.toolResult.Rule { val rule = Rule() - rule.ruleId = this.id + rule.sarifRuleId = this.id rule.shortDescription = this.shortDescription.text return rule } @@ -21,10 +21,7 @@ fun de.fraunhofer.iem.dataprovider.sarif.Rule.asDbObject(): de.fraunhofer.iem.da fun de.fraunhofer.iem.dataprovider.sarif.Tool.asDbObject(): Tool { val tool = Tool() - val rules = this.driver.rules.map { - it.asDbObject() - } - tool.rules = rules.toMutableSet() + tool.addRules(this.driver.rules.map { it.asDbObject() }) tool.name = this.driver.fullName tool.version = this.driver.version return tool @@ -36,13 +33,13 @@ fun Location.asDbObject(): ResultLocation { resultLocation.endLine = this.physicalLocation.region.endLine resultLocation.startColumn = this.physicalLocation.region.startColumn resultLocation.startLine = this.physicalLocation.region.startLine - resultLocation.artifactLocation = this.physicalLocation.artifactLocation.uri return resultLocation } -fun Result.asDbObject(): ToolResult { +fun Result.asDbObject(rules: Collection<Rule>): ToolResult { val toolResult = ToolResult() + when (this.level.uppercase(Locale.getDefault())) { "WARNING" -> toolResult.level = Level.Warning "ERROR" -> toolResult.level = Level.Error @@ -50,25 +47,23 @@ fun Result.asDbObject(): ToolResult { else -> toolResult.level = Level.None } + rules + .filter { it.sarifRuleId == this.ruleId } + .forEach { it.addResultLocation(toolResult) } + toolResult.message = this.message.text - val locations = this.locations.map { it.asDbObject() } - toolResult.resultLocations = locations.toMutableSet() + toolResult.addLocations(this.locations.map { it.asDbObject() }) return toolResult } fun Sarif.asDbObject(): List<ToolRun> { - - return this.runs.map { run -> val tr = ToolRun() - val tool = run.tool.asDbObject() - tr.tool = tool + tr.tool = run.tool.asDbObject() + tr.addToolResults(run.results.map { it.asDbObject(tr.tool!!.rules) }) tr.timeStamp = Timestamp.from(Instant.now()) - val results = run.results.map { it.asDbObject() } - tr.toolResults = results.toMutableSet() tr - } } diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/ProcessTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/ProcessTask.kt index b27c4c5812173bfb2c6c8e9f616cb4d748f09f58..cc7ec22e804affe081db6dee84b1cd9454bd1fd0 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/ProcessTask.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/ProcessTask.kt @@ -8,7 +8,6 @@ import de.fraunhofer.iem.dataprovider.toolResult.ToolRunRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import org.hibernate.Hibernate import org.springframework.transaction.annotation.Transactional import java.nio.file.Files import java.nio.file.Path @@ -44,14 +43,14 @@ sealed class ProcessTask : Task() { abstract suspend fun handleProcessReturn(p: Process) } - +@Transactional sealed class SarifTask : ProcessTask() { protected abstract val repoId: UUID protected abstract val repository: RepositoryRepository protected abstract val toolRunRepository: ToolRunRepository protected abstract val resultPath: Path - @Transactional + override suspend fun handleProcessReturn(p: Process) { // TODO: check process exit codes. Current problem, if an analysis @@ -59,15 +58,19 @@ sealed class SarifTask : ProcessTask() { logger.info("Handle Process return in $javaClass") val sarifResult = getSarifFromFilePath(resultPath) - val repo = repository.findById(repoId) - - val results = toolRunRepository.saveAll(sarifResult.asDbObject()) - - repo.ifPresent { - Hibernate.initialize(it.toolRuns) // TODO: this fails because the session seems to be closed and add won't work because toolRuns are loaded lazily - it.toolRuns.addAll(results) - repository.save(it) +// val repo = repository.findById(repoId) + val sarifDb = sarifResult.asDbObject() + val results = toolRunRepository.saveAll(sarifDb) + results.forEach { + val dbres = toolRunRepository.findById(it.id!!).get() +// Hibernate.initialize(dbres.toolResults) + logger.info(dbres.toString()) } +// repo.ifPresent { +// Hibernate.initialize(it.toolRuns) // TODO: this fails because the session seems to be closed and add won't work because toolRuns are loaded lazily +// it.toolRuns.addAll(results) +// repository.save(it) +// } sendResult(sarifResult) } diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRun.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRun.kt index 1c39b55d2c1bff88c26af5beb8fcb19204a49aff..6367b4814697b250ba8b9a8d2bba65026fd320f5 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRun.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRun.kt @@ -8,9 +8,13 @@ import org.hibernate.type.SqlTypes import java.sql.Timestamp import java.util.* +enum class Level { + Warning, Error, Note, None +} - - +enum class Kind { + pass, open, informational, notApplicable +} @Entity @Table(name = "tool_run") @@ -20,8 +24,6 @@ class ToolRun { @Column(name = "id", nullable = false) var id: UUID? = null - @OneToMany(mappedBy = "toolRun", orphanRemoval = true, cascade = [CascadeType.ALL]) - var toolResults: MutableSet<ToolResult> = mutableSetOf() @OneToOne(orphanRemoval = true, cascade = [CascadeType.ALL]) @JoinColumn(name = "tool_id") @@ -31,9 +33,22 @@ class ToolRun { @Column(name = "time_stamp") var timeStamp: Timestamp? = null - @ManyToOne - @JoinColumn(name = "repository_id") + @ManyToOne(fetch = FetchType.EAGER) var repository: Repository? = null + + @OneToMany(mappedBy = "toolRun", cascade = [CascadeType.ALL], orphanRemoval = true) + var toolResults: MutableSet<ToolResult> = mutableSetOf() + + fun addToolResults(toolResults: Collection<ToolResult>) { + toolResults.forEach { + this.addToolResult(it) + } + } + + fun addToolResult(toolResult: ToolResult) { + toolResults.add(toolResult) + toolResult.toolRun = this + } } @Entity @@ -44,24 +59,29 @@ class Tool { @Column(name = "id", nullable = false) var id: UUID? = null - @OneToMany(mappedBy = "tool", orphanRemoval = true, cascade = [CascadeType.ALL]) - var rules: MutableSet<Rule> = mutableSetOf() @Column(name = "name", length = 500) var name: String? = null @Column(name = "version") var version: String? = null -} -enum class Level { - Warning, Error, Note, None -} + @OneToMany(mappedBy = "tool", cascade = [CascadeType.ALL], orphanRemoval = true) + var rules: MutableSet<Rule> = mutableSetOf() -enum class Kind { - pass, open, informational, notApplicable + fun addRules(rules: Collection<Rule>) { + rules.forEach { + this.addRule(it) + } + } + + fun addRule(rule: Rule) { + rules.add(rule) + rule.tool = this + } } + @Entity @Table(name = "tool_result") class ToolResult { @@ -71,12 +91,22 @@ class ToolResult { var id: UUID? = null @ManyToOne - @JoinColumn(name = "tool_run_id") - var toolRun: ToolRun? = null + var rule: Rule? = null @OneToMany(mappedBy = "toolResult", cascade = [CascadeType.ALL], orphanRemoval = true) var resultLocations: MutableSet<ResultLocation> = mutableSetOf() + fun addLocations(locations: Collection<ResultLocation>) { + locations.forEach { + this.addLocation(it) + } + } + + fun addLocation(location: ResultLocation) { + resultLocations.add(location) + location.toolResult = this + } + @Enumerated @Column(name = "level") var level: Level? = null @@ -89,6 +119,9 @@ class ToolResult { @Column(name = "message") var message: String? = null + @ManyToOne + var toolRun: ToolRun? = null + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false @@ -109,13 +142,8 @@ class ResultLocation { var id: UUID? = null @ManyToOne - @JoinColumn(name = "tool_result_id") var toolResult: ToolResult? = null - @OneToOne(orphanRemoval = true) - @JoinColumn(name = "rule_id") - var rule: Rule? = null - @Lob @Column(name = "artifact_location") var artifactLocation: String? = null @@ -151,24 +179,36 @@ class Rule { @Column(name = "id", nullable = false) var id: UUID? = null - @ManyToOne - @JoinColumn(name = "tool_id") - var tool: Tool? = null - - @Column(name = "rule_id") - var ruleId: String? = null + @Column(name = "sarif_rule_id") + var sarifRuleId: String? = null @Lob @Column(name = "short_description") var shortDescription: String? = null + @OneToMany(mappedBy = "rule", cascade = [CascadeType.ALL], orphanRemoval = true) + var toolResults: MutableSet<ToolResult> = mutableSetOf() + + fun addResultLocations(toolResults: Collection<ToolResult>) { + toolResults.forEach { + this.addResultLocation(it) + } + } + + fun addResultLocation(toolResult: ToolResult) { + toolResults.add(toolResult) + toolResult.rule = this + } @ElementCollection @CollectionTable(name = "rule_messages", joinColumns = [JoinColumn(name = "owner_id")]) @Column(name = "message", length = 1000) var messages: MutableList<String> = mutableListOf() + @ManyToOne + var tool: Tool? = null + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRunRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRunRepository.kt index d0cc2c9c99637048c6470c132c0c4aafd89498c1..4a907621bbee277cc305a2a2751e59a93c5a8dac 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRunRepository.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolResult/ToolRunRepository.kt @@ -1,4 +1,4 @@ -package de.fraunhofer.iem.dataprovider.toolResult; +package de.fraunhofer.iem.dataprovider.toolResult import org.springframework.data.jpa.repository.JpaRepository import java.util.* diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c5716e4e45a53dffb17cfa1b00ca62be685bc70e..8dd67df9a324eb2314461c59a30415d9788e4e6a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,6 +8,7 @@ spring.datasource.username=sa spring.datasource.password=password spring.jpa.generate-ddl=true spring.jpa.show-sql=true +spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.format_sql=true GIT_PROJECT_PATH=${GIT_PROJECT_PATH} ODC_OUTPUT_PATH=${ODC_OUTPUT_PATH}