From 38d59c8961416c764ac0dccebcbab45cf2be3b99 Mon Sep 17 00:00:00 2001 From: Jan-Niclas Struewer <j.n.struewer@gmail.com> Date: Wed, 27 Sep 2023 14:45:52 +0200 Subject: [PATCH] create tool db objects upon application start iff they don't exist --- .../configuration/DirectoryPathsProperties.kt | 4 ---- .../dataprovider/kpi/metrics/MetricsService.kt | 13 ++++++++++++- .../service/RepositoryDetailsService.kt | 11 ++++++++++- .../iem/dataprovider/tool/entity/ToolEntity.kt | 4 ---- .../iem/dataprovider/tool/service/ToolService.kt | 4 ---- .../toolRun/service/ToolRunService.kt | 4 ++-- .../tools/occmd/service/OccmdService.kt | 16 +++++++++++++--- .../dataprovider/tools/ort/service/OrtService.kt | 12 +++++++++++- src/main/resources/application.properties | 13 ++++++------- 9 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt index 951661e2..93e693c5 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt @@ -19,15 +19,11 @@ data class DirectoryPathsProperties( @NotBlank @Length(min = 1) val gitCloneTargetDirectory: String, - @NotBlank - @Length(min = 1) - val toolResultsTargetDirectory: String ) { @PostConstruct fun postConstruct() { createDir(gitCloneTargetDirectory) - createDir(toolResultsTargetDirectory) } private fun createDir(stringPath: String) { diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/MetricsService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/MetricsService.kt index d3a99773..53c68767 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/MetricsService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/MetricsService.kt @@ -25,6 +25,7 @@ class MetricsService( private val defaultScope = CoroutineScope(Dispatchers.Default) val ioScope = CoroutineScope(Dispatchers.IO) + suspend fun handleRepositoryChange(repoId: Long) = defaultScope.launch { // TODO: we need to create the tools in the db and link them to the tool run. @@ -66,16 +67,24 @@ class MetricsService( val vulnerabilityKpis = async { val vulnerabilityDtos = ortService.getOrtResults(repoId) // in the dev setup we get results for repo id 106 - ortService.calculateVulnerabilityKpis(vulnerabilityDtos) + val kpis = ortService.calculateVulnerabilityKpis(vulnerabilityDtos) + if (kpis.isNotEmpty()) { + toolRun.toolEntities.add(ortService.toolEntity) + } + kpis } val repositoryDetailsKpi = async { val repoDetailsDto = repositoryDetailsService.getRepositoryDetails(repoId) + toolRun.toolEntities.add(repositoryDetailsService.toolEntity) repositoryDetailsService.calculateRepositoryDetailsKpis(repoDetailsDto) } val occmdKpis = async { val rawOccmdResults = occmdService.runOccmd(repoId, toolRun.repository?.url!!) + if (rawOccmdResults.isNotEmpty()) { + toolRun.toolEntities.add(occmdService.toolEntity) + } occmdService.calculateOccmdKpis(rawOccmdResults) } @@ -90,5 +99,7 @@ class MetricsService( vulnerabilityKpis = vulnerabilityKpis.await(), occmdKpis = occmdKpis.await() ) + + toolRunService.saveToolRunEntitiy(toolRun) } } diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/repositoryDetails/service/RepositoryDetailsService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/repositoryDetails/service/RepositoryDetailsService.kt index ab53011e..9e1821b8 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/repositoryDetails/service/RepositoryDetailsService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/metrics/repositoryDetails/service/RepositoryDetailsService.kt @@ -5,15 +5,24 @@ import de.fraunhofer.iem.dataprovider.kpi.dto.KPICreateDto import de.fraunhofer.iem.dataprovider.kpi.metrics.repositoryDetails.dto.RepositoryDetailsKpisDto import de.fraunhofer.iem.dataprovider.kpi.strategy.RawValueKPICalculationStrategy import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryDetailsDto +import de.fraunhofer.iem.dataprovider.tool.dto.CreateToolDto +import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity +import de.fraunhofer.iem.dataprovider.tool.service.ToolService import org.springframework.stereotype.Service @Service -class RepositoryDetailsService(private val openCodeGitlabApi: OpenCodeGitlabApi) { +class RepositoryDetailsService(private val openCodeGitlabApi: OpenCodeGitlabApi, private val toolService: ToolService) { suspend fun getRepositoryDetails(repoId: Long): RepositoryDetailsDto { return openCodeGitlabApi.getRepositoryDetails(repoId) } + val toolEntity: ToolEntity = getOrCreateToolEntity() + + private final fun getOrCreateToolEntity(): ToolEntity { + val createToolDto = CreateToolDto("Gitlab API") + return toolService.findOrCreateTool(createToolDto) + } /** * Creates a named map of RepositoryCreateDtos, based upon the provided repository details. diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/ToolEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/ToolEntity.kt index c9329074..7ba9a106 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/ToolEntity.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/ToolEntity.kt @@ -19,10 +19,6 @@ class ToolEntity { @Column(name = "name", length = 500) var name: String? = null - @Column(name = "api") - var api: String? = null - - @CurrentTimestamp(event = [EventType.INSERT]) var createdAt: Instant? = null diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/ToolService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/ToolService.kt index 05bb683e..a0285d0e 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/ToolService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/ToolService.kt @@ -10,10 +10,6 @@ class ToolService( private val toolRepository: ToolRepository, ) { - fun save(tool: ToolEntity) { - toolRepository.save(tool) - } - fun findOrCreateTool(tool: CreateToolDto): ToolEntity { return toolRepository.findByNameIgnoreCase( tool.name diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/service/ToolRunService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/service/ToolRunService.kt index f9c5b430..b9b34d27 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/service/ToolRunService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/service/ToolRunService.kt @@ -17,7 +17,7 @@ class ToolRunService(private val toolRunRepository: ToolRunRepository) { return toolRunRepository.save(tr) } - fun getLatestToolResultsForRepo(repo: RepositoryEntity): List<ToolRunEntity> { - return repo.toolRuns + fun saveToolRunEntitiy(toolRunEntity: ToolRunEntity): ToolRunEntity { + return toolRunRepository.save(toolRunEntity) } } diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt index cd5c9c87..3fd1e480 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt @@ -5,6 +5,9 @@ import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties import de.fraunhofer.iem.dataprovider.kpi.dto.KPICreateDto import de.fraunhofer.iem.dataprovider.kpi.strategy.RawValueKPICalculationStrategy import de.fraunhofer.iem.dataprovider.logger.getLogger +import de.fraunhofer.iem.dataprovider.tool.dto.CreateToolDto +import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity +import de.fraunhofer.iem.dataprovider.tool.service.ToolService import de.fraunhofer.iem.dataprovider.tools.occmd.dto.OccmdKpisDto import de.fraunhofer.iem.dataprovider.tools.occmd.enumeration.Checks import de.fraunhofer.iem.dataprovider.tools.occmd.json.RawResultJson @@ -25,11 +28,19 @@ import kotlin.io.path.deleteRecursively @Service class OccmdService( private val dirProperties: DirectoryPathsProperties, - private val gitlabApiProperties: OpenCodeGitlabApiProperties + private val gitlabApiProperties: OpenCodeGitlabApiProperties, + private val toolService: ToolService ) { val logger = getLogger(javaClass) + val toolEntity: ToolEntity = getOrCreateToolEntity() + + private final fun getOrCreateToolEntity(): ToolEntity { + val createToolDto = CreateToolDto("OCCMD") + return toolService.findOrCreateTool(createToolDto) + } + @OptIn(ExperimentalPathApi::class) suspend fun runOccmd(repoId: Long, repoUrl: String): List<RawResultJson> { // clone repo @@ -109,8 +120,7 @@ class OccmdService( toolResults.add(json.decodeFromString(it)) } } else { - logger.warn("Given execPath is not an executable $execPath.") - // TODO: we should probably throw an exception here. + logger.error("Given execPath is not an executable $execPath.") } return@coroutineScope toolResults diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt index 1b446dd5..24bcc0eb 100644 --- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt +++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt @@ -3,6 +3,9 @@ package de.fraunhofer.iem.dataprovider.tools.ort.service import de.fraunhofer.iem.dataprovider.configuration.OpenCodeApiProperties import de.fraunhofer.iem.dataprovider.kpi.dto.KPICreateDto import de.fraunhofer.iem.dataprovider.kpi.strategy.RawValueKPICalculationStrategy +import de.fraunhofer.iem.dataprovider.tool.dto.CreateToolDto +import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity +import de.fraunhofer.iem.dataprovider.tool.service.ToolService import de.fraunhofer.iem.dataprovider.tools.ort.dto.VulnerabilityDto import de.fraunhofer.iem.dataprovider.tools.ort.json.OrtJson import io.ktor.client.* @@ -16,7 +19,7 @@ import kotlinx.serialization.json.Json import org.springframework.stereotype.Service @Service -class OrtService(private val openCodeApiProperties: OpenCodeApiProperties) { +class OrtService(private val openCodeApiProperties: OpenCodeApiProperties, private val toolService: ToolService) { val client = HttpClient(CIO) { install(ContentNegotiation) { @@ -26,6 +29,13 @@ class OrtService(private val openCodeApiProperties: OpenCodeApiProperties) { } } + val toolEntity: ToolEntity = getOrCreateToolEntity() + + private final fun getOrCreateToolEntity(): ToolEntity { + val createToolDto = CreateToolDto("ORT") + return toolService.findOrCreateTool(createToolDto) + } + suspend fun getOrtResults(repoId: Long): List<VulnerabilityDto> { val response: HttpResponse = client.get(getToolApiPath(repoId)) val ortJson = response.body<OrtJson>() diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5a877d2a..d31e4dbc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,19 +8,14 @@ opencode.access-token=${OC_GL_APIKEY} opencode.api.base-path=https://sl.dev.o4oe.de/api/v1/project/ opencode.api.ort=/cve-result -# DB Login data -spring.datasource.url=${DB_URL} -#spring.datasource.url=jdbc:postgresql://${host}:26257/${DB_USER}?sslmode=${ssl_mode}&sslrootcert=${ca_crt}&sslcert=${ssl_cert}&sslkey=${ssl_key} -spring.datasource.username=${DB_USER} -spring.datasource.password=${DB_PW} # API key to access this server's API security.api-key=${API_KEY} security.admin-password=${ADMIN_PASSWORD} occmd.git-clone-target-directory=${GIT_CLONE_TARGET_DIRECTORY} -occmd.tool-results-target-directory=${TOOL_RESULTS_TARGET_DIRECTORY} occmd.occmd-path=${OCCMD_PATH} server.port=${PORT} + # Generates db schema if it doesn't exist in db spring.jpa.generate-ddl=true spring.jpa.show-sql=false @@ -31,4 +26,8 @@ spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false spring.jpa.open-in-view=false spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.CockroachDialect -#logging.level.root=DEBUG \ No newline at end of file +# DB Login data +spring.datasource.url=${DB_URL} +#spring.datasource.url=jdbc:postgresql://${host}:26257/${DB_USER}?sslmode=${ssl_mode}&sslrootcert=${ca_crt}&sslcert=${ssl_cert}&sslkey=${ssl_key} +spring.datasource.username=${DB_USER} +spring.datasource.password=${DB_PW} \ No newline at end of file -- GitLab