From d93106716f084cc9da4a021503dbf38ce9d8dfe0 Mon Sep 17 00:00:00 2001
From: Jan-Niclas Struewer <j.n.struewer@gmail.com>
Date: Mon, 30 Oct 2023 10:55:24 +0100
Subject: [PATCH] If a MaximumKPICalculationStrategy or
 AggregationKPICalculationStrategy has only empty children we set the KPI
 itself to empty.  This is done by throwing an error which should be caught
 when calculating the KPI

---
 .../fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt  | 3 +++
 .../kpi/strategy/AggregationKPICalculationStrategy.kt         | 4 ++++
 .../kpi/strategy/MaximumKPICalculationStrategy.kt             | 3 +++
 src/main/resources/application-local.properties               | 2 +-
 src/main/resources/application-prod.properties                | 1 +
 5 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt
index a850d284..e8add332 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt
@@ -2,6 +2,7 @@ package de.fraunhofer.iem.dataprovider.kpi.dto
 
 import de.fraunhofer.iem.dataprovider.kpi.enumeration.KpiKind
 import de.fraunhofer.iem.dataprovider.kpi.strategy.KPICalculationStrategy
+import de.fraunhofer.iem.dataprovider.logger.getLogger
 
 class KpiCalculationDto(
     val kind: KpiKind,
@@ -10,6 +11,7 @@ class KpiCalculationDto(
     private var value: Int? = null
 ) {
     private val hierarchyEdges: MutableList<KPIHierarchyEdgeDto> = mutableListOf()
+    private val logger = getLogger(javaClass)
 
     fun hasChildren(): Boolean {
         return hierarchyEdges.isNotEmpty()
@@ -29,6 +31,7 @@ class KpiCalculationDto(
                 this.value = calculationStrategy.calculateKPI(this.hierarchyEdges)
                 this.isEmpty = false
             } catch (exception: Exception) {
+                logger.error("Exception during KPI calculation for $kind with $calculationStrategy")
                 this.isEmpty = true
                 this.value = null
             }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/AggregationKPICalculationStrategy.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/AggregationKPICalculationStrategy.kt
index 905de83b..ca143284 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/AggregationKPICalculationStrategy.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/AggregationKPICalculationStrategy.kt
@@ -11,6 +11,10 @@ class AggregationKPICalculationStrategy : KPICalculationStrategy {
      * remaining children.
      */
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
+        if (children.none { !it.to.isEmpty() } || children.isEmpty()) {
+            throw Exception("KPI aggregation of empty children can't be calculated.")
+        }
+
         val emptyChildren: List<KPIHierarchyEdgeDto> = children.filter { it.to.isEmpty() }
         val notEmptyChildren = children.toMutableList()
         notEmptyChildren.removeAll(emptyChildren)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/MaximumKPICalculationStrategy.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/MaximumKPICalculationStrategy.kt
index a8823511..a65c51b7 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/MaximumKPICalculationStrategy.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/MaximumKPICalculationStrategy.kt
@@ -6,6 +6,9 @@ class MaximumKPICalculationStrategy : KPICalculationStrategy {
     // TODO: Currently it's tailored to the maximum dependency vulnerability score, this should change in the future
     @Suppress("MagicNumber")
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
+        if (children.none { !it.to.isEmpty() } || children.isEmpty()) {
+            throw Exception("KPI maximum of empty children can't be calculated")
+        }
         var maximum = 0
         for (child in children) {
             if (!child.to.isEmpty()) {
diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties
index 541c9ea2..b4ac9ba7 100644
--- a/src/main/resources/application-local.properties
+++ b/src/main/resources/application-local.properties
@@ -30,7 +30,7 @@ spring.main.web-application-type=REACTIVE
 spring.jpa.generate-ddl=true
 spring.jpa.show-sql=false
 # This setting should only be used in dev. In prod we want to switch to update
-spring.jpa.hibernate.ddl-auto=update
+spring.jpa.hibernate.ddl-auto=create-drop
 spring.jpa.properties.hibernate.format_sql=true
 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
 spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 4745c409..aa3c4832 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -5,6 +5,7 @@ opencode.host=https://gitlab.opencode.de/
 opencode.access-token=${OC_GL_APIKEY:}
 # Tool APIs
 opencode.api.base-path=https://sl.dev.o4oe.de/api/v1/project/
+# https://software.opencode.de as soon as it is live
 opencode.api.ort=/cve-result
 # API key to access this server's API
 #  The api key is needed for all routes.
-- 
GitLab