From 812d0031864eef6cbb5b7e0996429210aba21694 Mon Sep 17 00:00:00 2001 From: Jan-Niclas Struewer <j.n.struewer@gmail.com> Date: Mon, 29 Jul 2024 14:00:41 +0200 Subject: [PATCH] feature: changed result type of AdapterResult.kt and its implementing classes to the new AdapterResult.kt. The benefit is that we have one common result type for all adapters which can be either a success or an Error with a given ErrorType to indicate all consumers what went wrong during transformation. --- .../iem/app/toolRun/service/ToolRunService.kt | 12 +++++++-- .../iem/kpiCalculator/adapter/KpiAdapter.kt | 6 ++--- .../kpiCalculator/adapter/cve/CveAdapter.kt | 21 ++++++++++----- .../adapter/cve/CveAdapterTest.kt | 27 ++++++++++++++++--- .../model/adapter/AdapterResult.kt | 10 +++++++ 5 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/adapter/AdapterResult.kt diff --git a/app/backend/src/main/kotlin/de/fraunhofer/iem/app/toolRun/service/ToolRunService.kt b/app/backend/src/main/kotlin/de/fraunhofer/iem/app/toolRun/service/ToolRunService.kt index 2cc1888f..6c0a0dad 100644 --- a/app/backend/src/main/kotlin/de/fraunhofer/iem/app/toolRun/service/ToolRunService.kt +++ b/app/backend/src/main/kotlin/de/fraunhofer/iem/app/toolRun/service/ToolRunService.kt @@ -9,6 +9,7 @@ import de.fraunhofer.iem.app.tools.gitlab.service.RepositoryDetailsService import de.fraunhofer.iem.app.tools.occmd.service.OccmdService import de.fraunhofer.iem.app.tools.ort.service.OrtService import de.fraunhofer.iem.kpiCalculator.adapter.cve.CveAdapter +import de.fraunhofer.iem.kpiCalculator.model.adapter.AdapterResult import kotlinx.coroutines.* import org.springframework.stereotype.Service @@ -19,7 +20,7 @@ class ToolRunService( private val kpiService: KPIService, private val ortService: OrtService, private val occmdService: OccmdService, - private val repositoryService: RepositoryService + private val repositoryService: RepositoryService, ) { private val defaultScope = CoroutineScope(Dispatchers.Default) @@ -67,7 +68,14 @@ class ToolRunService( async { val vulnerabilityDtos = ortService.getOrtResults(projectId) // in the dev setup we get results for repo id 106 - Pair(ortService.getToolDto(), CveAdapter.transformDataToKpi(vulnerabilityDtos)) + //TODO: refactor the current processing of tool results to include error handling. Right now errors + // are silently dropped. This behavior is identical to the previous implementation and right now our + // goal is to match the behavior of the old implementation. + val rawValueKpiCreateDtos = + CveAdapter.transformDataToKpi(vulnerabilityDtos).filterIsInstance<AdapterResult.Success>() + .map { it.rawValueKpiCreateDto } + + Pair(ortService.getToolDto(), rawValueKpiCreateDtos) }, async { diff --git a/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/KpiAdapter.kt b/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/KpiAdapter.kt index 316c11b7..55633bc9 100644 --- a/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/KpiAdapter.kt +++ b/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/KpiAdapter.kt @@ -1,12 +1,12 @@ package de.fraunhofer.iem.kpiCalculator.adapter +import de.fraunhofer.iem.kpiCalculator.model.adapter.AdapterResult import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiKind -import de.fraunhofer.iem.kpiCalculator.model.kpi.RawValueKpiCreateDto interface KpiAdapter<T> { val kpiKind: KpiKind - fun transformDataToKpi(data: List<T>): List<RawValueKpiCreateDto> - fun transformDataToKpi(data: T): List<RawValueKpiCreateDto> = transformDataToKpi(listOf(data)) + fun transformDataToKpi(data: List<T>): List<AdapterResult> + fun transformDataToKpi(data: T): AdapterResult = transformDataToKpi(listOf(data)).first() } diff --git a/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapter.kt b/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapter.kt index 469d3490..9cb30699 100644 --- a/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapter.kt +++ b/kpi-calculator/adapter/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapter.kt @@ -1,6 +1,8 @@ package de.fraunhofer.iem.kpiCalculator.adapter.cve import de.fraunhofer.iem.kpiCalculator.adapter.KpiAdapter +import de.fraunhofer.iem.kpiCalculator.model.adapter.AdapterResult +import de.fraunhofer.iem.kpiCalculator.model.adapter.ErrorType import de.fraunhofer.iem.kpiCalculator.model.adapter.VulnerabilityDto import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiKind import de.fraunhofer.iem.kpiCalculator.model.kpi.RawValueKpiCreateDto @@ -9,18 +11,23 @@ object CveAdapter : KpiAdapter<VulnerabilityDto> { override val kpiKind: KpiKind get() = KpiKind.VULNERABILITY_SCORE - override fun transformDataToKpi(data: List<VulnerabilityDto>): List<RawValueKpiCreateDto> { + override fun transformDataToKpi(data: List<VulnerabilityDto>): List<AdapterResult> { return data - .filter(CveAdapter::filterData) .map { - RawValueKpiCreateDto( - kind = kpiKind, - score = (it.severity * 10).toInt() - ) + return@map if (isValid(it)) { + AdapterResult.Success( + RawValueKpiCreateDto( + kind = kpiKind, + score = (it.severity * 10).toInt() + ) + ) + } else { + AdapterResult.Error(ErrorType.DATA_VALIDATION_ERROR) + } } } - private fun filterData(data: VulnerabilityDto): Boolean { + private fun isValid(data: VulnerabilityDto): Boolean { return ( data.severity in 0.0..10.0 && data.packageName.isNotBlank() && diff --git a/kpi-calculator/adapter/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapterTest.kt b/kpi-calculator/adapter/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapterTest.kt index 578e221b..cb482bef 100644 --- a/kpi-calculator/adapter/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapterTest.kt +++ b/kpi-calculator/adapter/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/adapter/cve/CveAdapterTest.kt @@ -1,7 +1,10 @@ package de.fraunhofer.iem.kpiCalculator.adapter.cve +import de.fraunhofer.iem.kpiCalculator.model.adapter.AdapterResult +import de.fraunhofer.iem.kpiCalculator.model.adapter.ErrorType import de.fraunhofer.iem.kpiCalculator.model.adapter.VulnerabilityDto import org.junit.jupiter.api.Test +import kotlin.test.fail class CveAdapterTest { @@ -16,8 +19,15 @@ class CveAdapterTest { severity = 0.1 ) ) - assert(validKpi.isNotEmpty()) - assert(validKpi.first().score in (0..100)) + when (validKpi) { + is AdapterResult.Success -> { + assert(validKpi.rawValueKpiCreateDto.score in (0..100)) + } + + is AdapterResult.Error -> { + fail() + } + } // invalid input val invalidKpis = CveAdapter.transformDataToKpi( @@ -44,6 +54,17 @@ class CveAdapterTest { ) ) ) - assert(invalidKpis.isEmpty()) + + invalidKpis.forEach { invalidKpi -> + when (invalidKpi) { + is AdapterResult.Error -> { + assert(invalidKpi.type == ErrorType.DATA_VALIDATION_ERROR) + } + + is AdapterResult.Success -> { + fail() + } + } + } } } diff --git a/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/adapter/AdapterResult.kt b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/adapter/AdapterResult.kt new file mode 100644 index 00000000..6c71e534 --- /dev/null +++ b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/adapter/AdapterResult.kt @@ -0,0 +1,10 @@ +package de.fraunhofer.iem.kpiCalculator.model.adapter + +import de.fraunhofer.iem.kpiCalculator.model.kpi.RawValueKpiCreateDto + +enum class ErrorType { DATA_VALIDATION_ERROR } + +sealed class AdapterResult { + data class Success(val rawValueKpiCreateDto: RawValueKpiCreateDto) : AdapterResult() + data class Error(val type: ErrorType) : AdapterResult() +} -- GitLab