From f4592f1d46f251158f427e859c20857b79462206 Mon Sep 17 00:00:00 2001 From: Kamil Bielecki Date: Fri, 20 Sep 2024 09:35:37 +0200 Subject: [PATCH] feat(service): Add RuleViolationService Add service for rule violations results with companion objects. Signed-off-by: Kamil Bielecki --- .../kotlin/RuleViolationWithIdentifier.kt | 28 +++ .../kotlin/runs/evaluator/RuleViolation.kt | 31 +++ .../src/main/kotlin/RuleViolationService.kt | 88 +++++++++ .../test/kotlin/RuleViolationServiceTest.kt | 180 ++++++++++++++++++ 4 files changed, 327 insertions(+) create mode 100644 model/src/commonMain/kotlin/RuleViolationWithIdentifier.kt create mode 100644 model/src/commonMain/kotlin/runs/evaluator/RuleViolation.kt create mode 100644 services/hierarchy/src/main/kotlin/RuleViolationService.kt create mode 100644 services/hierarchy/src/test/kotlin/RuleViolationServiceTest.kt diff --git a/model/src/commonMain/kotlin/RuleViolationWithIdentifier.kt b/model/src/commonMain/kotlin/RuleViolationWithIdentifier.kt new file mode 100644 index 0000000000..087a6c8779 --- /dev/null +++ b/model/src/commonMain/kotlin/RuleViolationWithIdentifier.kt @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 The ORT Server Authors (See ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.eclipse.apoapsis.ortserver.model + +import org.eclipse.apoapsis.ortserver.model.runs.Identifier +import org.eclipse.apoapsis.ortserver.model.runs.evaluator.RuleViolation + +data class RuleViolationWithIdentifier( + val ruleViolation: RuleViolation, + val identifier: Identifier, +) diff --git a/model/src/commonMain/kotlin/runs/evaluator/RuleViolation.kt b/model/src/commonMain/kotlin/runs/evaluator/RuleViolation.kt new file mode 100644 index 0000000000..89e6cc9cc0 --- /dev/null +++ b/model/src/commonMain/kotlin/runs/evaluator/RuleViolation.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 The ORT Server Authors (See ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.eclipse.apoapsis.ortserver.model.runs.evaluator + +import org.eclipse.apoapsis.ortserver.model.Severity + +data class RuleViolation( + val rule: String, + val license: String?, + val licenseSource: String?, + val severity: Severity, + val message: String, + val howToFix: String +) diff --git a/services/hierarchy/src/main/kotlin/RuleViolationService.kt b/services/hierarchy/src/main/kotlin/RuleViolationService.kt new file mode 100644 index 0000000000..02c0925044 --- /dev/null +++ b/services/hierarchy/src/main/kotlin/RuleViolationService.kt @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2024 The ORT Server Authors (See ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.eclipse.apoapsis.ortserver.services + +import org.eclipse.apoapsis.ortserver.dao.dbQuery +import org.eclipse.apoapsis.ortserver.dao.tables.EvaluatorJobsTable +import org.eclipse.apoapsis.ortserver.dao.tables.runs.evaluator.EvaluatorRunsRuleViolationsTable +import org.eclipse.apoapsis.ortserver.dao.tables.runs.evaluator.EvaluatorRunsTable +import org.eclipse.apoapsis.ortserver.dao.tables.runs.evaluator.RuleViolationDao +import org.eclipse.apoapsis.ortserver.dao.tables.runs.evaluator.RuleViolationsTable +import org.eclipse.apoapsis.ortserver.dao.tables.runs.shared.IdentifiersTable +import org.eclipse.apoapsis.ortserver.dao.utils.listCustomQuery +import org.eclipse.apoapsis.ortserver.model.RuleViolationWithIdentifier +import org.eclipse.apoapsis.ortserver.model.runs.Identifier +import org.eclipse.apoapsis.ortserver.model.runs.evaluator.RuleViolation +import org.eclipse.apoapsis.ortserver.model.util.ListQueryParameters +import org.eclipse.apoapsis.ortserver.model.util.ListQueryResult + +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.ResultRow + +class RuleViolationService(private val db: Database) { + suspend fun listForOrtRunId( + ortRunId: Long, + parameters: ListQueryParameters = ListQueryParameters.DEFAULT + ): ListQueryResult = db.dbQuery { + val ruleViolationQueryResult = + RuleViolationDao.listCustomQuery(parameters, ResultRow::toRuleViolation) { + val join = RuleViolationsTable innerJoin + EvaluatorRunsRuleViolationsTable innerJoin + EvaluatorRunsTable innerJoin + EvaluatorJobsTable innerJoin + IdentifiersTable + + join.select( + RuleViolationsTable.rule, + RuleViolationsTable.license, + RuleViolationsTable.licenseSource, + RuleViolationsTable.severity, + RuleViolationsTable.message, + RuleViolationsTable.howToFix, + IdentifiersTable.id, + IdentifiersTable.type, + IdentifiersTable.namespace, + IdentifiersTable.name, + IdentifiersTable.version + ).where { EvaluatorJobsTable.ortRunId eq ortRunId } + } + + ListQueryResult(ruleViolationQueryResult.data, parameters, ruleViolationQueryResult.totalCount) + } +} + +private fun ResultRow.toRuleViolation(): RuleViolationWithIdentifier { + return RuleViolationWithIdentifier( + RuleViolation( + this[RuleViolationsTable.rule], + this[RuleViolationsTable.license], + this[RuleViolationsTable.licenseSource], + this[RuleViolationsTable.severity], + this[RuleViolationsTable.message], + this[RuleViolationsTable.howToFix] + ), + Identifier( + this[IdentifiersTable.type], + this[IdentifiersTable.namespace], + this[IdentifiersTable.name], + this[IdentifiersTable.version] + ) + ) +} diff --git a/services/hierarchy/src/test/kotlin/RuleViolationServiceTest.kt b/services/hierarchy/src/test/kotlin/RuleViolationServiceTest.kt new file mode 100644 index 0000000000..4c345266bc --- /dev/null +++ b/services/hierarchy/src/test/kotlin/RuleViolationServiceTest.kt @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2024 The ORT Server Authors (See ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.eclipse.apoapsis.ortserver.services + +import io.kotest.core.spec.style.WordSpec +import io.kotest.matchers.collections.shouldHaveSize +import io.kotest.matchers.shouldBe + +import kotlinx.datetime.Clock + +import org.eclipse.apoapsis.ortserver.dao.test.DatabaseTestExtension +import org.eclipse.apoapsis.ortserver.dao.test.Fixtures +import org.eclipse.apoapsis.ortserver.dao.utils.toDatabasePrecision +import org.eclipse.apoapsis.ortserver.model.EvaluatorJobConfiguration +import org.eclipse.apoapsis.ortserver.model.JobConfigurations +import org.eclipse.apoapsis.ortserver.model.OrtRun +import org.eclipse.apoapsis.ortserver.model.Severity +import org.eclipse.apoapsis.ortserver.model.runs.Identifier +import org.eclipse.apoapsis.ortserver.model.runs.OrtRuleViolation +import org.eclipse.apoapsis.ortserver.model.runs.evaluator.RuleViolation + +import org.jetbrains.exposed.sql.Database + +class RuleViolationServiceTest : WordSpec() { + + private val dbExtension = extension(DatabaseTestExtension()) + + private lateinit var db: Database + private lateinit var fixtures: Fixtures + + init { + beforeEach { + db = dbExtension.db + fixtures = dbExtension.fixtures + } + + "listForOrtRunId" should { + "return the rule violations for the given ORT run ID" { + val service = RuleViolationService(db) + + val ruleViolations = createRuleViolations( + Pair( + RuleViolation( + "Rule-1", + "License-1", + "CONCLUDED", + Severity.WARNING, + "Message-1", + "How_to_fix-1" + ), + Identifier( + "Maven", + "org.apache.logging.log4j", + "log4j-core", + "2.14.0" + ) + ), + Pair( + RuleViolation( + "Rule-2", + "License-2", + "DETECTED", + Severity.ERROR, + "Message-2", + "How_to_fix-2" + ), + Identifier( + "Maven", + "com.fasterxml.jackson.core", + "jackson-databind", + "2.9.6" + ) + ) + ) + + val ortRun = createRuleViolationEntries(ruleViolations) + val results = service.listForOrtRunId(ortRun.id).data + + results shouldHaveSize 2 + + with(results[0]) { + with(ruleViolation) { + rule shouldBe "Rule-1" + license shouldBe "License-1" + licenseSource shouldBe "CONCLUDED" + severity shouldBe Severity.WARNING + message shouldBe "Message-1" + howToFix shouldBe "How_to_fix-1" + } + + with(identifier) { + type shouldBe "Maven" + namespace shouldBe "org.apache.logging.log4j" + name shouldBe "log4j-core" + version shouldBe "2.14.0" + } + } + + with(results[1]) { + with(ruleViolation) { + rule shouldBe "Rule-2" + license shouldBe "License-2" + licenseSource shouldBe "DETECTED" + severity shouldBe Severity.ERROR + message shouldBe "Message-2" + howToFix shouldBe "How_to_fix-2" + } + + with(identifier) { + type shouldBe "Maven" + namespace shouldBe "com.fasterxml.jackson.core" + name shouldBe "jackson-databind" + version shouldBe "2.9.6" + } + } + } + } + } + + private fun createRuleViolations(vararg ruleViolations: Pair): List { + val ortRuleViolations = mutableListOf() + ruleViolations.forEach { + val identifier = fixtures.createIdentifier(it.second) + + ortRuleViolations += OrtRuleViolation( + it.first.rule, + identifier, + it.first.license, + it.first.licenseSource, + it.first.severity, + it.first.message, + it.first.howToFix + ) + } + return ortRuleViolations + } + + private fun createRuleViolationEntries(ruleViolations: List): OrtRun { + val repository = fixtures.createRepository() + + fixtures.createIdentifier() + + val ortRun = fixtures.createOrtRun( + repositoryId = repository.id, + revision = "revision", + jobConfigurations = JobConfigurations() + ) + + val evaluatorJob = fixtures.createEvaluatorJob( + ortRunId = ortRun.id, + configuration = EvaluatorJobConfiguration() + ) + + fixtures.evaluatorRunRepository.create( + evaluatorJobId = evaluatorJob.id, + startTime = Clock.System.now().toDatabasePrecision(), + endTime = Clock.System.now().toDatabasePrecision(), + violations = ruleViolations + ) + + return ortRun + } +}