Skip to content

Commit

Permalink
feat(service): Add RuleViolationService
Browse files Browse the repository at this point in the history
Add service for rule violations results with companion objects.

Signed-off-by: Kamil Bielecki <[email protected]>
  • Loading branch information
Kamil Bielecki committed Sep 30, 2024
1 parent 2706be7 commit f4592f1
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 0 deletions.
28 changes: 28 additions & 0 deletions model/src/commonMain/kotlin/RuleViolationWithIdentifier.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2024 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
*
* 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,
)
31 changes: 31 additions & 0 deletions model/src/commonMain/kotlin/runs/evaluator/RuleViolation.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2024 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
*
* 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
)
88 changes: 88 additions & 0 deletions services/hierarchy/src/main/kotlin/RuleViolationService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2024 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
*
* 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<RuleViolationWithIdentifier> = 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]
)
)
}
180 changes: 180 additions & 0 deletions services/hierarchy/src/test/kotlin/RuleViolationServiceTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright (C) 2024 The ORT Server Authors (See <https://github.com/eclipse-apoapsis/ort-server/blob/main/NOTICE>)
*
* 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<RuleViolation, Identifier>): List<OrtRuleViolation> {
val ortRuleViolations = mutableListOf<OrtRuleViolation>()
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<OrtRuleViolation>): 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
}
}

0 comments on commit f4592f1

Please sign in to comment.