From 2859d317b9e23218cfc94f6c1f0c3058a69bf137 Mon Sep 17 00:00:00 2001
From: Jan-Niclas Struewer <j.n.struewer@gmail.com>
Date: Wed, 11 Oct 2023 13:22:58 +0200
Subject: [PATCH] Reworked KPI calculation. Added first error handling and
 tests. Added new API query system. ATTENTION: ORT URL currently hardcoded for
 repository id 106 due to test setup

---
 .editorconfig                                 |  491 ++
 .gitlab-ci.yml                                |   88 +-
 README.md                                     |   30 +-
 build.gradle.kts                              |   50 +-
 kubernetes/configmap.yaml                     |   10 +-
 kubernetes/deployment.yaml                    |  124 +-
 kubernetes/service.yaml                       |   14 +-
 .../dataprovider/DataProviderApplication.kt   |   11 +-
 .../dataprovider/configuration/ApiPaths.kt    |   16 +-
 .../configuration/DirectoryPathsProperties.kt |   16 +-
 .../configuration/OpenCodeApiProperties.kt    |   26 +
 .../OpenCodeGitlabApiProperties.kt            |    4 +-
 .../security/SecurityProperties.kt            |   13 +-
 .../security/WebFluxConfiguration.kt          |   12 +-
 .../security/WebSecurityConfiguration.kt      |   11 +-
 .../debug/controller/MetricsController.kt     |   43 -
 .../iem/dataprovider/debug/dto/FindingDto.kt  |    3 -
 .../iem/dataprovider/debug/dto/RepoDto.kt     |    3 -
 .../iem/dataprovider/debug/dto/ToolDto.kt     |    3 -
 .../dataprovider/debug/dto/ToolResultsDto.kt  |    3 -
 .../iem/dataprovider/debug/dto/ToolRunDto.kt  |    5 -
 .../dependency/dto/DependencyCreateDto.kt     |   22 -
 .../dependency/dto/VulnerabilityCreateDto.kt  |   21 -
 .../dto/VulnerabilityScoreCreateDto.kt        |   16 -
 .../dependency/entity/DependencyEntity.kt     |   63 -
 .../dependency/entity/VulnerabilityEntity.kt  |   38 -
 .../entity/VulnerabilityScoreEntity.kt        |   37 -
 .../VulnerabilityScoringSystemEnum.kt         |   13 -
 .../repository/DependencyRepository.kt        |   13 -
 .../dependency/service/DependencyService.kt   |   22 -
 .../gitlab/controller/GitlabController.kt     |   13 +-
 .../gitlab/dto/RepositoryChangedDto.kt        |    3 +-
 .../gitlab/enumeration/PlatformEnum.kt        |    5 -
 .../gitlab/service/GitlabService.kt           |   16 -
 .../gitlab/service/OpenCodeGitlabApi.kt       |   87 +
 .../kpi/controller/KPIController.kt           |   34 -
 .../kpi/dto/KPIChildResponseDto.kt            |    5 -
 .../iem/dataprovider/kpi/dto/KPICreateDto.kt  |   38 -
 .../kpi/dto/KPIHierarchyEdgeDto.kt            |    2 +-
 .../dataprovider/kpi/dto/KPIResponseDto.kt    |   14 -
 .../kpi/dto/KPITreeChildResponseDto.kt        |    3 +
 .../kpi/dto/KPITreeResponseDto.kt             |   13 +
 .../dataprovider/kpi/dto/KpiCalculationDto.kt |   63 +
 .../kpi/dto/RawValueKpiCreateDto.kt           |   18 +
 .../iem/dataprovider/kpi/entity/KPIEntity.kt  |   63 +-
 .../kpi/entity/KPIHierarchyEdgeEntity.kt      |   24 -
 .../dataprovider/kpi/enumeration/KpiKind.kt   |  215 +
 .../repository/KPIHierarchyEdgeRepository.kt  |    7 -
 .../kpi/repository/KPIRepository.kt           |    4 +-
 .../dataprovider/kpi/service/KPIService.kt    |  295 +-
 .../AggregationKPICalculationStrategy.kt      |   14 +-
 .../kpi/strategy/KPICalculationStrategy.kt    |    3 +-
 .../strategy/MaximumKPICalculationStrategy.kt |   13 +-
 .../strategy/RatioKPICalculationStrategy.kt   |   14 +-
 .../RawValueKPICalculationStrategy.kt         |    6 +-
 .../controller/RepositoryController.kt        |   63 +-
 .../repository/dto/RepositoryCreateDto.kt     |   16 +-
 .../dto/RepositoryDetailsCreateDto.kt         |   20 -
 .../repository/dto/RepositoryDetailsDto.kt    |    8 +
 .../repository/dto/RepositoryResponseDto.kt   |    3 +-
 .../repository/dto/ScoreCardResponseDto.kt    |    8 +
 .../entity/RepositoryDetailsEntity.kt         |   35 -
 .../repository/entity/RepositoryEntity.kt     |   53 +-
 .../repository/RepositoryDetailsRepository.kt |   10 -
 .../repository/RepositoryRepository.kt        |    4 +-
 .../repository/service/RepositoryService.kt   |   40 +-
 .../taskManager/GroupTaskManager.kt           |   48 -
 .../dataprovider/taskManager/TaskManager.kt   |  196 -
 .../iem/dataprovider/taskManager/Worker.kt    |  102 -
 .../dataprovider/taskManager/events/Event.kt  |    2 -
 .../events/GetGitlabProjectDoneEvent.kt       |    7 -
 .../events/GetRepositoryDetailsDoneEvent.kt   |   10 -
 .../taskManager/events/GitCloneDoneEvent.kt   |    5 -
 .../taskManager/events/GroupTaskDoneEvent.kt  |    8 -
 .../events/GroupTaskFailedEvent.kt            |    5 -
 .../taskManager/events/GroupTasksDoneEvent.kt |    5 -
 .../events/OrtAnalyzerDoneEvent.kt            |    8 -
 .../events/RecalculateAllKpisEvent.kt         |    3 -
 .../taskManager/events/RepoChangedEvent.kt    |    3 -
 .../taskManager/events/TaskDoneEvent.kt       |    5 -
 .../taskManager/events/TaskFailedEvent.kt     |    3 -
 .../taskManager/model/GroupTasks.kt           |    8 -
 .../dataprovider/taskManager/tasks/Task.kt    |   39 -
 .../tasks/dataQuery/CloneGitTask.kt           |   34 -
 .../dataQuery/GetGitlabProjectInfoTask.kt     |   37 -
 .../dataQuery/GetRepositoryDetailsTask.kt     |   75 -
 .../tasks/kpiCalculation/MetricsTask.kt       |  169 -
 .../tasks/tools/ToolProcessTask.kt            |   78 -
 .../tasks/tools/occmd/OccmdTask.kt            |   89 -
 .../tools/occmd/json/sarif/OccmdSarif.kt      |   46 -
 .../taskManager/tasks/tools/ort/OrtApiTask.kt |  133 -
 .../tasks/tools/ort/dto/OrtResultDto.kt       |    9 -
 .../tools/ort/json/AdvisorInResultJson.kt     |   13 -
 .../tasks/tools/ort/json/AdvisorJson.kt       |   11 -
 .../tasks/tools/ort/json/AdvisorResultJson.kt |   16 -
 .../tasks/tools/ort/json/AnalyzerJson.kt      |   10 -
 .../tools/ort/json/AnalyzerResultJson.kt      |   23 -
 .../tasks/tools/ort/json/IssueJson.kt         |   17 -
 .../tasks/tools/ort/json/OrtJson.kt           |   14 -
 .../tasks/tools/ort/json/PackageJson.kt       |   10 -
 .../tasks/tools/ort/json/ResultsJson.kt       |   12 -
 .../tasks/tools/ort/json/SummaryJson.kt       |   15 -
 .../tasks/tools/ort/json/VulnerabilityJson.kt |   13 -
 .../dataprovider/tool/dto/CreateToolDto.kt    |    7 +-
 .../dataprovider/tool/entity/RuleEntity.kt    |   54 -
 .../dataprovider/tool/entity/ToolEntity.kt    |   24 +-
 .../tool/repository/RuleRepository.kt         |    9 -
 .../tool/repository/ToolRepository.kt         |    7 +-
 .../dataprovider/tool/service/RuleService.kt  |   16 -
 .../dataprovider/tool/service/ToolService.kt  |   11 +-
 .../toolRun/entity/FindingEntity.kt           |   53 -
 .../toolRun/entity/LocationEntity.kt          |   42 -
 .../toolRun/entity/ToolRunEntity.kt           |   52 +-
 .../toolRun/enumeration/LevelEnum.kt          |    5 -
 .../toolRun/repository/ToolRunRepository.kt   |    4 +-
 .../toolRun/service/ToolRunService.kt         |  160 +-
 .../service/RepositoryDetailsService.kt       |   23 +
 .../tools/occmd/enumeration/Checks.kt         |   11 +
 .../tools/occmd/json/RawResultJson.kt         |   21 +
 .../tools/occmd/json/SecretResultsJson.kt     |   11 +
 .../tools/occmd/json/ToolSecretJson.kt        |   13 +
 .../tools/occmd/json/ToolSecretResultJson.kt  |   13 +
 .../tools/occmd/service/OccmdService.kt       |  108 +
 .../tools/ort/dto/VulnerabilityDto.kt         |    3 +
 .../dataprovider/tools/ort/json/DataJson.kt   |   17 +
 .../dataprovider/tools/ort/json/OrtJson.kt    |   13 +
 .../tools/ort/json/ReferenceJson.kt           |    2 +-
 .../dataprovider/tools/ort/json/ResultJson.kt |   27 +
 .../tools/ort/service/OrtService.kt           |   91 +
 src/main/resources/application.properties     |   34 +-
 src/main/resources/scripts/occmd.sh           |   12 +-
 src/main/resources/scripts/ort/config.yml     |    5 -
 src/main/resources/scripts/ort/ort_advisor.sh |   16 -
 .../resources/scripts/ort/ort_analyzer.sh     |   16 -
 .../dataprovider/DependencyDatabaseTest.kt    |   49 -
 .../fraunhofer/iem/dataprovider/WorkerTest.kt |   51 -
 .../dataprovider/ort/OrtAdvisorTaskTest.kt    |   40 -
 .../dataprovider/ort/ParseOrtAdvisorResult.kt |   80 -
 .../ort/ort-advisor-example-results.json      |  158 -
 .../tools/ort/service/OrtServiceTest.kt       |  123 +
 src/test/resources/application.properties     |    9 +-
 tools/db/api.json                             | 4240 +----------------
 tools/db/docker-compose.yml                   |   34 +-
 143 files changed, 2299 insertions(+), 7099 deletions(-)
 create mode 100644 .editorconfig
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeApiProperties.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/controller/MetricsController.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/FindingDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/RepoDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolResultsDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolRunDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/DependencyCreateDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityCreateDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityScoreCreateDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/DependencyEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityScoreEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/enumeration/VulnerabilityScoringSystemEnum.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/repository/DependencyRepository.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/service/DependencyService.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/enumeration/PlatformEnum.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/GitlabService.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/controller/KPIController.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIChildResponseDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPICreateDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIResponseDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeChildResponseDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeResponseDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/RawValueKpiCreateDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIHierarchyEdgeEntity.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/enumeration/KpiKind.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIHierarchyEdgeRepository.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsCreateDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ScoreCardResponseDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryDetailsEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryDetailsRepository.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/GroupTaskManager.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/TaskManager.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/Worker.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/Event.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetGitlabProjectDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetRepositoryDetailsDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GitCloneDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskFailedEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTasksDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/OrtAnalyzerDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RecalculateAllKpisEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RepoChangedEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskDoneEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskFailedEvent.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/model/GroupTasks.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/Task.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/CloneGitTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetGitlabProjectInfoTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetRepositoryDetailsTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/kpiCalculation/MetricsTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ToolProcessTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/OccmdTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/json/sarif/OccmdSarif.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/OrtApiTask.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/dto/OrtResultDto.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorInResultJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorResultJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerResultJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/IssueJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/OrtJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/PackageJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ResultsJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/SummaryJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/VulnerabilityJson.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/RuleEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/RuleRepository.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/RuleService.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/FindingEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/LocationEntity.kt
 delete mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/enumeration/LevelEnum.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/gitlab/service/RepositoryDetailsService.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/enumeration/Checks.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/RawResultJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/SecretResultsJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretResultJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/dto/VulnerabilityDto.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/DataJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/OrtJson.kt
 rename src/main/kotlin/de/fraunhofer/iem/dataprovider/{taskManager/tasks => }/tools/ort/json/ReferenceJson.kt (80%)
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ResultJson.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt
 delete mode 100644 src/main/resources/scripts/ort/config.yml
 delete mode 100755 src/main/resources/scripts/ort/ort_advisor.sh
 delete mode 100755 src/main/resources/scripts/ort/ort_analyzer.sh
 delete mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/DependencyDatabaseTest.kt
 delete mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/WorkerTest.kt
 delete mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/OrtAdvisorTaskTest.kt
 delete mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ParseOrtAdvisorResult.kt
 delete mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json
 create mode 100644 src/test/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtServiceTest.kt

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..b4f8aef2
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,491 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+max_line_length = 120
+tab_width = 4
+ij_continuation_indent_size = 8
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = true
+ij_smart_tabs = false
+ij_visual_guides =
+ij_wrap_on_typing = false
+
+[*.java]
+ij_java_align_consecutive_assignments = false
+ij_java_align_consecutive_variable_declarations = false
+ij_java_align_group_field_declarations = false
+ij_java_align_multiline_annotation_parameters = false
+ij_java_align_multiline_array_initializer_expression = false
+ij_java_align_multiline_assignment = false
+ij_java_align_multiline_binary_operation = false
+ij_java_align_multiline_chained_methods = false
+ij_java_align_multiline_deconstruction_list_components = true
+ij_java_align_multiline_extends_list = false
+ij_java_align_multiline_for = true
+ij_java_align_multiline_method_parentheses = false
+ij_java_align_multiline_parameters = true
+ij_java_align_multiline_parameters_in_calls = false
+ij_java_align_multiline_parenthesized_expression = false
+ij_java_align_multiline_records = true
+ij_java_align_multiline_resources = true
+ij_java_align_multiline_ternary_operation = false
+ij_java_align_multiline_text_blocks = false
+ij_java_align_multiline_throws_list = false
+ij_java_align_subsequent_simple_methods = false
+ij_java_align_throws_keyword = false
+ij_java_align_types_in_multi_catch = true
+ij_java_annotation_parameter_wrap = off
+ij_java_array_initializer_new_line_after_left_brace = false
+ij_java_array_initializer_right_brace_on_new_line = false
+ij_java_array_initializer_wrap = off
+ij_java_assert_statement_colon_on_next_line = false
+ij_java_assert_statement_wrap = off
+ij_java_assignment_wrap = off
+ij_java_binary_operation_sign_on_next_line = false
+ij_java_binary_operation_wrap = off
+ij_java_blank_lines_after_anonymous_class_header = 0
+ij_java_blank_lines_after_class_header = 0
+ij_java_blank_lines_after_imports = 1
+ij_java_blank_lines_after_package = 1
+ij_java_blank_lines_around_class = 1
+ij_java_blank_lines_around_field = 0
+ij_java_blank_lines_around_field_in_interface = 0
+ij_java_blank_lines_around_initializer = 1
+ij_java_blank_lines_around_method = 1
+ij_java_blank_lines_around_method_in_interface = 1
+ij_java_blank_lines_before_class_end = 0
+ij_java_blank_lines_before_imports = 1
+ij_java_blank_lines_before_method_body = 0
+ij_java_blank_lines_before_package = 0
+ij_java_block_brace_style = end_of_line
+ij_java_block_comment_add_space = false
+ij_java_block_comment_at_first_column = true
+ij_java_builder_methods =
+ij_java_call_parameters_new_line_after_left_paren = false
+ij_java_call_parameters_right_paren_on_new_line = false
+ij_java_call_parameters_wrap = off
+ij_java_case_statement_on_separate_line = true
+ij_java_catch_on_new_line = false
+ij_java_class_annotation_wrap = split_into_lines
+ij_java_class_brace_style = end_of_line
+ij_java_class_count_to_use_import_on_demand = 5
+ij_java_class_names_in_javadoc = 1
+ij_java_deconstruction_list_wrap = normal
+ij_java_do_not_indent_top_level_class_members = false
+ij_java_do_not_wrap_after_single_annotation = false
+ij_java_do_not_wrap_after_single_annotation_in_parameter = false
+ij_java_do_while_brace_force = never
+ij_java_doc_add_blank_line_after_description = true
+ij_java_doc_add_blank_line_after_param_comments = false
+ij_java_doc_add_blank_line_after_return = false
+ij_java_doc_add_p_tag_on_empty_lines = true
+ij_java_doc_align_exception_comments = true
+ij_java_doc_align_param_comments = true
+ij_java_doc_do_not_wrap_if_one_line = false
+ij_java_doc_enable_formatting = true
+ij_java_doc_enable_leading_asterisks = true
+ij_java_doc_indent_on_continuation = false
+ij_java_doc_keep_empty_lines = true
+ij_java_doc_keep_empty_parameter_tag = true
+ij_java_doc_keep_empty_return_tag = true
+ij_java_doc_keep_empty_throws_tag = true
+ij_java_doc_keep_invalid_tags = true
+ij_java_doc_param_description_on_new_line = false
+ij_java_doc_preserve_line_breaks = false
+ij_java_doc_use_throws_not_exception_tag = true
+ij_java_else_on_new_line = false
+ij_java_entity_dd_prefix =
+ij_java_entity_dd_suffix = EJB
+ij_java_entity_eb_prefix =
+ij_java_entity_eb_suffix = Bean
+ij_java_entity_hi_prefix =
+ij_java_entity_hi_suffix = Home
+ij_java_entity_lhi_prefix = Local
+ij_java_entity_lhi_suffix = Home
+ij_java_entity_li_prefix = Local
+ij_java_entity_li_suffix =
+ij_java_entity_pk_class = java.lang.String
+ij_java_entity_ri_prefix =
+ij_java_entity_ri_suffix =
+ij_java_entity_vo_prefix =
+ij_java_entity_vo_suffix = VO
+ij_java_enum_constants_wrap = off
+ij_java_extends_keyword_wrap = off
+ij_java_extends_list_wrap = off
+ij_java_field_annotation_wrap = split_into_lines
+ij_java_field_name_prefix =
+ij_java_field_name_suffix =
+ij_java_filter_class_prefix =
+ij_java_filter_class_suffix =
+ij_java_filter_dd_prefix =
+ij_java_filter_dd_suffix =
+ij_java_finally_on_new_line = false
+ij_java_for_brace_force = never
+ij_java_for_statement_new_line_after_left_paren = false
+ij_java_for_statement_right_paren_on_new_line = false
+ij_java_for_statement_wrap = off
+ij_java_generate_final_locals = false
+ij_java_generate_final_parameters = false
+ij_java_if_brace_force = never
+ij_java_imports_layout = *, |, javax.**, java.**, |, $*
+ij_java_indent_case_from_switch = true
+ij_java_insert_inner_class_imports = false
+ij_java_insert_override_annotation = true
+ij_java_keep_blank_lines_before_right_brace = 2
+ij_java_keep_blank_lines_between_package_declaration_and_header = 2
+ij_java_keep_blank_lines_in_code = 2
+ij_java_keep_blank_lines_in_declarations = 2
+ij_java_keep_builder_methods_indents = false
+ij_java_keep_control_statement_in_one_line = true
+ij_java_keep_first_column_comment = true
+ij_java_keep_indents_on_empty_lines = false
+ij_java_keep_line_breaks = true
+ij_java_keep_multiple_expressions_in_one_line = false
+ij_java_keep_simple_blocks_in_one_line = false
+ij_java_keep_simple_classes_in_one_line = false
+ij_java_keep_simple_lambdas_in_one_line = false
+ij_java_keep_simple_methods_in_one_line = false
+ij_java_label_indent_absolute = false
+ij_java_label_indent_size = 0
+ij_java_lambda_brace_style = end_of_line
+ij_java_layout_static_imports_separately = true
+ij_java_line_comment_add_space = false
+ij_java_line_comment_add_space_on_reformat = false
+ij_java_line_comment_at_first_column = true
+ij_java_listener_class_prefix =
+ij_java_listener_class_suffix =
+ij_java_local_variable_name_prefix =
+ij_java_local_variable_name_suffix =
+ij_java_message_dd_prefix =
+ij_java_message_dd_suffix = EJB
+ij_java_message_eb_prefix =
+ij_java_message_eb_suffix = Bean
+ij_java_method_annotation_wrap = split_into_lines
+ij_java_method_brace_style = end_of_line
+ij_java_method_call_chain_wrap = off
+ij_java_method_parameters_new_line_after_left_paren = false
+ij_java_method_parameters_right_paren_on_new_line = false
+ij_java_method_parameters_wrap = off
+ij_java_modifier_list_wrap = false
+ij_java_multi_catch_types_wrap = normal
+ij_java_names_count_to_use_import_on_demand = 3
+ij_java_new_line_after_lparen_in_annotation = false
+ij_java_new_line_after_lparen_in_deconstruction_pattern = true
+ij_java_new_line_after_lparen_in_record_header = false
+ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.*
+ij_java_parameter_annotation_wrap = off
+ij_java_parameter_name_prefix =
+ij_java_parameter_name_suffix =
+ij_java_parentheses_expression_new_line_after_left_paren = false
+ij_java_parentheses_expression_right_paren_on_new_line = false
+ij_java_place_assignment_sign_on_next_line = false
+ij_java_prefer_longer_names = true
+ij_java_prefer_parameters_wrap = false
+ij_java_record_components_wrap = normal
+ij_java_repeat_annotations =
+ij_java_repeat_synchronized = true
+ij_java_replace_instanceof_and_cast = false
+ij_java_replace_null_check = true
+ij_java_replace_sum_lambda_with_method_ref = true
+ij_java_resource_list_new_line_after_left_paren = false
+ij_java_resource_list_right_paren_on_new_line = false
+ij_java_resource_list_wrap = off
+ij_java_rparen_on_new_line_in_annotation = false
+ij_java_rparen_on_new_line_in_deconstruction_pattern = true
+ij_java_rparen_on_new_line_in_record_header = false
+ij_java_servlet_class_prefix =
+ij_java_servlet_class_suffix =
+ij_java_servlet_dd_prefix =
+ij_java_servlet_dd_suffix =
+ij_java_session_dd_prefix =
+ij_java_session_dd_suffix = EJB
+ij_java_session_eb_prefix =
+ij_java_session_eb_suffix = Bean
+ij_java_session_hi_prefix =
+ij_java_session_hi_suffix = Home
+ij_java_session_lhi_prefix = Local
+ij_java_session_lhi_suffix = Home
+ij_java_session_li_prefix = Local
+ij_java_session_li_suffix =
+ij_java_session_ri_prefix =
+ij_java_session_ri_suffix =
+ij_java_session_si_prefix =
+ij_java_session_si_suffix = Service
+ij_java_space_after_closing_angle_bracket_in_type_argument = false
+ij_java_space_after_colon = true
+ij_java_space_after_comma = true
+ij_java_space_after_comma_in_type_arguments = true
+ij_java_space_after_for_semicolon = true
+ij_java_space_after_quest = true
+ij_java_space_after_type_cast = true
+ij_java_space_before_annotation_array_initializer_left_brace = false
+ij_java_space_before_annotation_parameter_list = false
+ij_java_space_before_array_initializer_left_brace = false
+ij_java_space_before_catch_keyword = true
+ij_java_space_before_catch_left_brace = true
+ij_java_space_before_catch_parentheses = true
+ij_java_space_before_class_left_brace = true
+ij_java_space_before_colon = true
+ij_java_space_before_colon_in_foreach = true
+ij_java_space_before_comma = false
+ij_java_space_before_deconstruction_list = false
+ij_java_space_before_do_left_brace = true
+ij_java_space_before_else_keyword = true
+ij_java_space_before_else_left_brace = true
+ij_java_space_before_finally_keyword = true
+ij_java_space_before_finally_left_brace = true
+ij_java_space_before_for_left_brace = true
+ij_java_space_before_for_parentheses = true
+ij_java_space_before_for_semicolon = false
+ij_java_space_before_if_left_brace = true
+ij_java_space_before_if_parentheses = true
+ij_java_space_before_method_call_parentheses = false
+ij_java_space_before_method_left_brace = true
+ij_java_space_before_method_parentheses = false
+ij_java_space_before_opening_angle_bracket_in_type_parameter = false
+ij_java_space_before_quest = true
+ij_java_space_before_switch_left_brace = true
+ij_java_space_before_switch_parentheses = true
+ij_java_space_before_synchronized_left_brace = true
+ij_java_space_before_synchronized_parentheses = true
+ij_java_space_before_try_left_brace = true
+ij_java_space_before_try_parentheses = true
+ij_java_space_before_type_parameter_list = false
+ij_java_space_before_while_keyword = true
+ij_java_space_before_while_left_brace = true
+ij_java_space_before_while_parentheses = true
+ij_java_space_inside_one_line_enum_braces = false
+ij_java_space_within_empty_array_initializer_braces = false
+ij_java_space_within_empty_method_call_parentheses = false
+ij_java_space_within_empty_method_parentheses = false
+ij_java_spaces_around_additive_operators = true
+ij_java_spaces_around_annotation_eq = true
+ij_java_spaces_around_assignment_operators = true
+ij_java_spaces_around_bitwise_operators = true
+ij_java_spaces_around_equality_operators = true
+ij_java_spaces_around_lambda_arrow = true
+ij_java_spaces_around_logical_operators = true
+ij_java_spaces_around_method_ref_dbl_colon = false
+ij_java_spaces_around_multiplicative_operators = true
+ij_java_spaces_around_relational_operators = true
+ij_java_spaces_around_shift_operators = true
+ij_java_spaces_around_type_bounds_in_type_parameters = true
+ij_java_spaces_around_unary_operator = false
+ij_java_spaces_within_angle_brackets = false
+ij_java_spaces_within_annotation_parentheses = false
+ij_java_spaces_within_array_initializer_braces = false
+ij_java_spaces_within_braces = false
+ij_java_spaces_within_brackets = false
+ij_java_spaces_within_cast_parentheses = false
+ij_java_spaces_within_catch_parentheses = false
+ij_java_spaces_within_deconstruction_list = false
+ij_java_spaces_within_for_parentheses = false
+ij_java_spaces_within_if_parentheses = false
+ij_java_spaces_within_method_call_parentheses = false
+ij_java_spaces_within_method_parentheses = false
+ij_java_spaces_within_parentheses = false
+ij_java_spaces_within_record_header = false
+ij_java_spaces_within_switch_parentheses = false
+ij_java_spaces_within_synchronized_parentheses = false
+ij_java_spaces_within_try_parentheses = false
+ij_java_spaces_within_while_parentheses = false
+ij_java_special_else_if_treatment = true
+ij_java_static_field_name_prefix =
+ij_java_static_field_name_suffix =
+ij_java_subclass_name_prefix =
+ij_java_subclass_name_suffix = Impl
+ij_java_ternary_operation_signs_on_next_line = false
+ij_java_ternary_operation_wrap = off
+ij_java_test_name_prefix =
+ij_java_test_name_suffix = Test
+ij_java_throws_keyword_wrap = off
+ij_java_throws_list_wrap = off
+ij_java_use_external_annotations = false
+ij_java_use_fq_class_names = false
+ij_java_use_relative_indents = false
+ij_java_use_single_class_imports = true
+ij_java_variable_annotation_wrap = off
+ij_java_visibility = public
+ij_java_while_brace_force = never
+ij_java_while_on_new_line = false
+ij_java_wrap_comments = false
+ij_java_wrap_first_method_in_call_chain = false
+ij_java_wrap_long_lines = false
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = false
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = normal
+ij_xml_block_comment_add_space = false
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+ij_xml_use_custom_settings = false
+
+[{*.bash,*.sh,*.zsh}]
+indent_size = 2
+tab_width = 2
+ij_shell_binary_ops_start_line = false
+ij_shell_keep_column_alignment_padding = false
+ij_shell_minify_program = false
+ij_shell_redirect_followed_by_space = false
+ij_shell_switch_cases_indented = false
+ij_shell_use_unix_line_separator = true
+
+[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
+indent_size = 2
+ij_json_array_wrapping = split_into_lines
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_keep_trailing_comma = false
+ij_json_object_wrapping = split_into_lines
+ij_json_property_alignment = do_not_align
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = false
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+
+[{*.http,*.rest}]
+indent_size = 0
+ij_continuation_indent_size = 4
+ij_http-request_call_parameters_wrap = normal
+ij_http-request_method_parameters_wrap = split_into_lines
+ij_http-request_space_before_comma = true
+ij_http-request_spaces_around_assignment_operators = true
+
+[{*.kt,*.kts}]
+ij_kotlin_align_in_columns_case_branch = false
+ij_kotlin_align_multiline_binary_operation = false
+ij_kotlin_align_multiline_extends_list = false
+ij_kotlin_align_multiline_method_parentheses = false
+ij_kotlin_align_multiline_parameters = true
+ij_kotlin_align_multiline_parameters_in_calls = false
+ij_kotlin_allow_trailing_comma = false
+ij_kotlin_allow_trailing_comma_on_call_site = false
+ij_kotlin_assignment_wrap = normal
+ij_kotlin_blank_lines_after_class_header = 0
+ij_kotlin_blank_lines_around_block_when_branches = 0
+ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
+ij_kotlin_block_comment_add_space = false
+ij_kotlin_block_comment_at_first_column = true
+ij_kotlin_call_parameters_new_line_after_left_paren = true
+ij_kotlin_call_parameters_right_paren_on_new_line = true
+ij_kotlin_call_parameters_wrap = on_every_item
+ij_kotlin_catch_on_new_line = false
+ij_kotlin_class_annotation_wrap = split_into_lines
+ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
+ij_kotlin_continuation_indent_for_chained_calls = false
+ij_kotlin_continuation_indent_for_expression_bodies = false
+ij_kotlin_continuation_indent_in_argument_lists = false
+ij_kotlin_continuation_indent_in_elvis = false
+ij_kotlin_continuation_indent_in_if_conditions = false
+ij_kotlin_continuation_indent_in_parameter_lists = false
+ij_kotlin_continuation_indent_in_supertype_lists = false
+ij_kotlin_else_on_new_line = false
+ij_kotlin_enum_constants_wrap = off
+ij_kotlin_extends_list_wrap = normal
+ij_kotlin_field_annotation_wrap = split_into_lines
+ij_kotlin_finally_on_new_line = false
+ij_kotlin_if_rparen_on_new_line = true
+ij_kotlin_import_nested_classes = false
+ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^
+ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
+ij_kotlin_keep_blank_lines_before_right_brace = 2
+ij_kotlin_keep_blank_lines_in_code = 2
+ij_kotlin_keep_blank_lines_in_declarations = 2
+ij_kotlin_keep_first_column_comment = true
+ij_kotlin_keep_indents_on_empty_lines = false
+ij_kotlin_keep_line_breaks = true
+ij_kotlin_lbrace_on_next_line = false
+ij_kotlin_line_break_after_multiline_when_entry = true
+ij_kotlin_line_comment_add_space = false
+ij_kotlin_line_comment_add_space_on_reformat = false
+ij_kotlin_line_comment_at_first_column = true
+ij_kotlin_method_annotation_wrap = split_into_lines
+ij_kotlin_method_call_chain_wrap = normal
+ij_kotlin_method_parameters_new_line_after_left_paren = true
+ij_kotlin_method_parameters_right_paren_on_new_line = true
+ij_kotlin_method_parameters_wrap = on_every_item
+ij_kotlin_name_count_to_use_star_import = 5
+ij_kotlin_name_count_to_use_star_import_for_members = 3
+ij_kotlin_packages_to_use_import_on_demand = java.util.*, kotlinx.android.synthetic.**, io.ktor.**
+ij_kotlin_parameter_annotation_wrap = off
+ij_kotlin_space_after_comma = true
+ij_kotlin_space_after_extend_colon = true
+ij_kotlin_space_after_type_colon = true
+ij_kotlin_space_before_catch_parentheses = true
+ij_kotlin_space_before_comma = false
+ij_kotlin_space_before_extend_colon = true
+ij_kotlin_space_before_for_parentheses = true
+ij_kotlin_space_before_if_parentheses = true
+ij_kotlin_space_before_lambda_arrow = true
+ij_kotlin_space_before_type_colon = false
+ij_kotlin_space_before_when_parentheses = true
+ij_kotlin_space_before_while_parentheses = true
+ij_kotlin_spaces_around_additive_operators = true
+ij_kotlin_spaces_around_assignment_operators = true
+ij_kotlin_spaces_around_equality_operators = true
+ij_kotlin_spaces_around_function_type_arrow = true
+ij_kotlin_spaces_around_logical_operators = true
+ij_kotlin_spaces_around_multiplicative_operators = true
+ij_kotlin_spaces_around_range = false
+ij_kotlin_spaces_around_relational_operators = true
+ij_kotlin_spaces_around_unary_operator = false
+ij_kotlin_spaces_around_when_arrow = true
+ij_kotlin_variable_annotation_wrap = off
+ij_kotlin_while_on_new_line = false
+ij_kotlin_wrap_elvis_expressions = 1
+ij_kotlin_wrap_expression_body_functions = 1
+ij_kotlin_wrap_first_method_in_call_chain = false
+
+[{*.markdown,*.md}]
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_format_tables = true
+ij_markdown_insert_quote_arrows_on_wrap = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_keep_line_breaks_inside_text_blocks = true
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+ij_markdown_wrap_text_if_long = true
+ij_markdown_wrap_text_inside_blockquotes = true
+
+[{*.properties,spring.handlers,spring.schemas}]
+ij_properties_align_group_field_declarations = false
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = false
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 91dd7cc0..28b62b3e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,54 +1,54 @@
 stages:
-  - clone
-  - build
-  - deploy
+    - clone
+    - build
+    - deploy
 
 clone_occmd:
-  image: alpine/git
-  stage: clone
-  only:
-    - main
-  script:
-    - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.opencode.de/opencode-analyzer/occmd
-  artifacts:
-    paths:
-      - occmd/
+    image: alpine/git
+    stage: clone
+    only:
+        - main
+    script:
+        - git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.opencode.de/opencode-analyzer/occmd
+    artifacts:
+        paths:
+            - occmd/
 .base:
-  image:
-    name: gcr.io/kaniko-project/executor:debug
-    entrypoint: [""]
-  cache: {}
-  tags:
-    - "opencode-high"
-  before_script:
-    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
+    image:
+        name: gcr.io/kaniko-project/executor:debug
+        entrypoint: [ "" ]
+    cache: { }
+    tags:
+        - "opencode-high"
+    before_script:
+        - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
 
 build_sha:
-  extends: .base
-  stage: build
-  only:
-    - main
-  script:
-    - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}"
-  dependencies:
-    - clone_occmd
+    extends: .base
+    stage: build
+    only:
+        - main
+    script:
+        - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}"
+    dependencies:
+        - clone_occmd
 
 build_latest:
-  extends: .base
-  stage: build
-  only:
-    - main
-  script:
-    - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:latest"
-  dependencies:
-    - clone_occmd
+    extends: .base
+    stage: build
+    only:
+        - main
+    script:
+        - /kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" --destination "${CI_REGISTRY_IMAGE}:latest"
+    dependencies:
+        - clone_occmd
 
 deploy:
-  image: bitnami/kubectl
-  before_script:
-    - export KUBECONFIG=$KUBECONFIG_FILE
-  stage: deploy
-  only:
-    - main
-  script:
-    - kubectl set image -f ./kubernetes/deployment.yaml b-dev-container=registry.opencode.de/opencode-analyzer/data-provider:${CI_COMMIT_SHORT_SHA} --namespace=fraunhofer --local -o yaml | kubectl apply --namespace=fraunhofer -f -
+    image: bitnami/kubectl
+    before_script:
+        - export KUBECONFIG=$KUBECONFIG_FILE
+    stage: deploy
+    only:
+        - main
+    script:
+        - kubectl set image -f ./kubernetes/deployment.yaml b-dev-container=registry.opencode.de/opencode-analyzer/data-provider:${CI_COMMIT_SHORT_SHA} --namespace=fraunhofer --local -o yaml | kubectl apply --namespace=fraunhofer -f -
diff --git a/README.md b/README.md
index 8730d286..bfdfeaec 100644
--- a/README.md
+++ b/README.md
@@ -4,23 +4,38 @@
 
 1. Start the database docker service in `tools/db`.
 2. Install [OCCMD](https://gitlab.opencode.de/opencode-analyzer/occmd-public.git) and edit the
-   script `resources/scripts/occmd.sh` to point at the installation directory
+   script `resources/scripts/occmd.sh` to point at the executable.
+   The default implementation of the script expects a docker container with the name occmd to be present. A Dockerfile
+   is contained in this repository in `tools/occmd`.
 3. Set the necessary environment variables, which are used in the application.properties:
 
 ```
-opencode.access-token=${OC_GL_APIKEY}
+opencode.access-token=${OC_GL_APIKEY} // this is the api key for opencode
 
 # 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}
+// either connect to a local postgresql db or the deployed test db
+// the test db is a cockroach db and the expected url schema looks as follows:
+// #spring.datasource.url=jdbc:postgresql://${host}:26257/${DB_USER}?sslmode=${ssl_mode}&sslrootcert=${ca_crt}&sslcert=${ssl_cert}&sslkey=${ssl_key}
+spring.datasource.url=${DB_URL} 
 spring.datasource.username=${DB_USER}
 spring.datasource.password=${DB_PW}
 
+# OCCMD specific settings
+// path to the occmd tool executable
+// this can e.g, be the occmd.sh script in this project
+occmd.occmd-path=${OCCMD_PATH}
+
 # API key to access this server's API
+// The api key is needed for all routes.
+// the admin password is needed for the repo changed route.
+// It is expected as basic auth with the admin username
+// details can be found in configuration/security/WebSecurityConfiguration.kt
 security.api-key=${API_KEY}
+security.admin-username=${ADMIN_PASSWORD}
 security.admin-password=${ADMIN_PASSWORD}
+// a local repository to which the git repositories are temporarily cloned.
+// they are automatically deleted after every tool run.
 directories.git-clone-target-directory=${GIT_CLONE_TARGET_DIRECTORY}
-directories.tool-results-target-directory=${TOOL_RESULTS_TARGET_DIRECTORY}
 
 server.port=${PORT}
 ```
@@ -32,6 +47,7 @@ This file is automatically loaded by the IDE.
 4. Import the project into your IDE or use the commandline to build the application and run the server. For details on
    how to run the program manually consider the spring boot documentation.
 
-## Tests
+### Important Note for the dev deployment and testing.
 
-To run the e2e tests make sure to install the git submodules in the test directory.
\ No newline at end of file
+The dev ORT API doesn't have results for all projects. Thus make sure to edit the `MetricsService.kt` to
+point to the repository with id 106 for testing purposes.
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 9287bacc..934cac52 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,7 @@
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
-    id("org.springframework.boot") version "3.1.3"
+    id("org.springframework.boot") version "3.1.4"
     id("io.spring.dependency-management") version "1.1.3"
     id("org.jetbrains.kotlin.plugin.allopen") version "1.9.10"
     kotlin("jvm") version "1.9.10"
@@ -33,34 +33,36 @@ repositories {
 }
 
 dependencies {
-    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
-    implementation("org.springframework.boot:spring-boot-starter-validation")
-    implementation("org.springframework.boot:spring-boot-starter-security")
-    implementation("org.springframework.boot:spring-boot-starter-webflux")
-    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
-    implementation("org.jetbrains.kotlin:kotlin-reflect")
-    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
-    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactive")
-    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
+    implementation("org.springframework.boot:spring-boot-starter-data-jpa:3.1.4")
+    implementation("org.springframework.boot:spring-boot-starter-validation:3.1.4")
+    implementation("org.springframework.boot:spring-boot-starter-security:3.1.4")
+    implementation("org.springframework.boot:spring-boot-starter-webflux:3.1.4")
+    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2")
+    implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.10")
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactive:1.7.3")
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.7.3")
     implementation("org.gitlab4j:gitlab4j-api:6.0.0-rc.2")
-    implementation("org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r")
+    implementation("org.eclipse.jgit:org.eclipse.jgit:6.7.0.202309050840-r")
     implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
-    implementation("org.springframework.boot:spring-boot-starter-actuator")
-    implementation("io.ktor:ktor-client-core-jvm:2.3.4")
-    implementation("io.ktor:ktor-client-cio-jvm:2.3.4")
-    implementation("io.ktor:ktor-client-content-negotiation:2.3.4")
-    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.4")
-    developmentOnly("org.springframework.boot:spring-boot-devtools")
-    runtimeOnly("org.postgresql:postgresql")
-    testImplementation("org.springframework.boot:spring-boot-starter-test") {
+    implementation("org.springframework.boot:spring-boot-starter-actuator:3.1.4")
+    implementation("io.ktor:ktor-client-core-jvm:2.3.5")
+    implementation("io.ktor:ktor-client-cio-jvm:2.3.5")
+    implementation("io.ktor:ktor-client-content-negotiation:2.3.5")
+    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.5")
+    developmentOnly("org.springframework.boot:spring-boot-devtools:3.1.4")
+    runtimeOnly("org.postgresql:postgresql:42.6.0")
+    testImplementation("org.springframework.boot:spring-boot-starter-test:3.1.4") {
         exclude(module = "mockito-core")
+        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
     }
-    testImplementation("org.junit.jupiter:junit-jupiter-api")
-    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
-    testRuntimeOnly("com.h2database:h2")
+    testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.2")
+    testImplementation("io.ktor:ktor-client-mock:2.3.5")
+    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.2")
+    testRuntimeOnly("com.h2database:h2:2.2.224")
     testImplementation("com.ninja-squad:springmockk:4.0.2")
-    testImplementation("org.springframework.security:spring-security-test")
-    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.2")
+    testImplementation("org.springframework.security:spring-security-test:6.1.4")
+    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
 }
 
 tasks.withType<KotlinCompile> {
diff --git a/kubernetes/configmap.yaml b/kubernetes/configmap.yaml
index 80222aef..56111fa3 100644
--- a/kubernetes/configmap.yaml
+++ b/kubernetes/configmap.yaml
@@ -1,9 +1,9 @@
 apiVersion: v1
 kind: ConfigMap
 metadata:
-  name: data-provider-dev-config-map
-  namespace: fraunhofer
+    name: data-provider-dev-config-map
+    namespace: fraunhofer
 data:
-  GIT_CLONE_TARGET_DIRECTORY: "/app/git"
-  TOOL_RESULTS_TARGET_DIRECTORY: "/app/toolresults"
-  PORT: "5000"
\ No newline at end of file
+    GIT_CLONE_TARGET_DIRECTORY: "/app/git"
+    TOOL_RESULTS_TARGET_DIRECTORY: "/app/toolresults"
+    PORT: "5000"
\ No newline at end of file
diff --git a/kubernetes/deployment.yaml b/kubernetes/deployment.yaml
index 21565fe9..55df8018 100644
--- a/kubernetes/deployment.yaml
+++ b/kubernetes/deployment.yaml
@@ -1,66 +1,66 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
-  name: b-dev-deployment
-  annotations:
-    field.cattle.io/description: Backend of Fraunhofer OpenCoDE Analyzer
-  labels:
-    workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
-  namespace: fraunhofer
-spec:
-  selector:
-    matchLabels:
-      workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
-  template:
-    metadata:
-      labels:
+    name: b-dev-deployment
+    annotations:
+        field.cattle.io/description: Backend of Fraunhofer OpenCoDE Analyzer
+    labels:
         workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
-      namespace: fraunhofer
-    spec:
-      securityContext:
-        runAsNonRoot: true
-      volumes:
-        - name: db-secret-volume
-          secret:
-            secretName: cockroachdb.client.fraunhoferpoc
-      containers:
-        - imagePullPolicy: Always
-          name: b-dev-container
-          image: registry.opencode.de/opencode-analyzer/data-provider:latest
-          volumeMounts:
-            - mountPath: "/cockroach-certs"
-              name: db-secret-volume
-              readOnly: true
-          resources:
-            limits:
-              cpu: 8000m
-              memory: 16G
-            requests:
-              cpu: 4000m
-              memory: 8G
-          ports:
-            - name: b-dev-service
-              containerPort: 5000
-          env:
-            - name: ADMIN_PASSWORD
-              valueFrom:
-                secretKeyRef:
-                  name: backendapisecrets
-                  key: admin_password
-            - name: OC_GL_APIKEY
-              valueFrom:
-                secretKeyRef:
-                  name: backendapisecrets
-                  key: oc_api_key
-            - name: API_KEY
-              valueFrom:
-                secretKeyRef:
-                  name: backendapisecrets
-                  key: api_key
-          envFrom:
-            - configMapRef:
-                name: crdbconf
-            - configMapRef:
-                name: data-provider-dev-config-map
-      restartPolicy: Always
-  replicas: 1
+    namespace: fraunhofer
+spec:
+    selector:
+        matchLabels:
+            workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
+    template:
+        metadata:
+            labels:
+                workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
+            namespace: fraunhofer
+        spec:
+            securityContext:
+                runAsNonRoot: true
+            volumes:
+                -   name: db-secret-volume
+                    secret:
+                        secretName: cockroachdb.client.fraunhoferpoc
+            containers:
+                -   imagePullPolicy: Always
+                    name: b-dev-container
+                    image: registry.opencode.de/opencode-analyzer/data-provider:latest
+                    volumeMounts:
+                        -   mountPath: "/cockroach-certs"
+                            name: db-secret-volume
+                            readOnly: true
+                    resources:
+                        limits:
+                            cpu: 8000m
+                            memory: 16G
+                        requests:
+                            cpu: 4000m
+                            memory: 8G
+                    ports:
+                        -   name: b-dev-service
+                            containerPort: 5000
+                    env:
+                        -   name: ADMIN_PASSWORD
+                            valueFrom:
+                                secretKeyRef:
+                                    name: backendapisecrets
+                                    key: admin_password
+                        -   name: OC_GL_APIKEY
+                            valueFrom:
+                                secretKeyRef:
+                                    name: backendapisecrets
+                                    key: oc_api_key
+                        -   name: API_KEY
+                            valueFrom:
+                                secretKeyRef:
+                                    name: backendapisecrets
+                                    key: api_key
+                    envFrom:
+                        -   configMapRef:
+                                name: crdbconf
+                        -   configMapRef:
+                                name: data-provider-dev-config-map
+            restartPolicy: Always
+    replicas: 1
diff --git a/kubernetes/service.yaml b/kubernetes/service.yaml
index b8376535..9bcc5ff8 100644
--- a/kubernetes/service.yaml
+++ b/kubernetes/service.yaml
@@ -1,11 +1,11 @@
 apiVersion: v1
 kind: Service
 metadata:
-  name: b-dev-service
-  namespace: fraunhofer
+    name: b-dev-service
+    namespace: fraunhofer
 spec:
-  selector:
-    workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
-  ports:
-    - port: 5000
-      targetPort: 5000
+    selector:
+        workload.user.cattle.io/workloadselector: apps.deployment-fraunhofer-b-dev-deployment
+    ports:
+        -   port: 5000
+            targetPort: 5000
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
index 27be12dc..1f80ce8e 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
@@ -1,19 +1,12 @@
 package de.fraunhofer.iem.dataprovider
 
-import de.fraunhofer.iem.dataprovider.configuration.DirectoryPathsProperties
-import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
-import de.fraunhofer.iem.dataprovider.configuration.security.SecurityProperties
 import org.springframework.boot.autoconfigure.SpringBootApplication
-import org.springframework.boot.context.properties.EnableConfigurationProperties
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan
 import org.springframework.boot.runApplication
 
 
 @SpringBootApplication
-@EnableConfigurationProperties(
-    DirectoryPathsProperties::class,
-    OpenCodeGitlabApiProperties::class,
-    SecurityProperties::class
-)
+@ConfigurationPropertiesScan("de.fraunhofer.iem.dataprovider.configuration")
 class DataProviderApplication
 
 fun main(args: Array<String>) {
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/ApiPaths.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/ApiPaths.kt
index ee908de2..4964e2c4 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/ApiPaths.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/ApiPaths.kt
@@ -3,17 +3,13 @@ package de.fraunhofer.iem.dataprovider.configuration
 object ApiPaths {
     private const val BASE = "/api"
 
-    const val GITLAB = "$BASE/gitlab"
-    const val GITLAB_REPO_CHANGED = "$GITLAB/repoChanged"
-
-    const val DEBUG = "$BASE/debug/metrics"
-    const val DEBUG_LATEST_RUN = "$DEBUG/latestRuns/{platform}/{id}"
-    const val DEBUG_RECALCULATE_KPIS = "$DEBUG/recalculateAllKPIs"
-
-    const val KPI = "$BASE/kpi"
-    const val KPI_ID = "$KPI/{id}"
-    const val KPI_ROOT_REPOSITORY = "$KPI/root/repository/{id}"
+    private const val GITLAB = "$BASE/gitlab"
+    const val OPENCODE_REPO_CHANGED = "$GITLAB/opencode/repoChanged"
 
     const val REPOSITORY = "$BASE/repository"
+    const val REPOSITORY_SCORE_CARD = "$BASE/repository/scorecard"
+    const val SCORE_CARD_BY_REPOSITORY_ID = "$BASE/repository/{id}/scorecard"
+    const val KPI_BY_REPOSITORY_ID = "$BASE/repository/{id}/kpi"
+
     const val REPOSITORY_ID = "$REPOSITORY/{id}"
 }
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 802f0f61..b09be70c 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/DirectoryPathsProperties.kt
@@ -4,26 +4,28 @@ import jakarta.annotation.PostConstruct
 import jakarta.validation.constraints.NotBlank
 import org.hibernate.validator.constraints.Length
 import org.springframework.boot.context.properties.ConfigurationProperties
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan
 import org.springframework.validation.annotation.Validated
 import java.nio.file.Path
 import java.nio.file.Paths
 import kotlin.io.path.createDirectories
 
-@ConfigurationProperties(prefix = "directories")
+@ConfigurationProperties(prefix = "occmd")
+@ConfigurationPropertiesScan
 @Validated
 data class DirectoryPathsProperties(
-    @NotBlank
-    @Length(min = 1)
+    @field:NotBlank
+    @field:Length(min = 1)
+    val occmdPath: String,
+
+    @field:NotBlank
+    @field: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/configuration/OpenCodeApiProperties.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeApiProperties.kt
new file mode 100644
index 00000000..aaea2fcc
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeApiProperties.kt
@@ -0,0 +1,26 @@
+package de.fraunhofer.iem.dataprovider.configuration
+
+import jakarta.annotation.PostConstruct
+import jakarta.validation.constraints.NotBlank
+import org.springframework.boot.context.properties.ConfigurationProperties
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan
+import org.springframework.validation.annotation.Validated
+import java.net.URL
+
+
+@ConfigurationProperties(prefix = "opencode.api")
+@ConfigurationPropertiesScan
+@Validated
+data class OpenCodeApiProperties(
+    @field:NotBlank
+    val basePath: String,
+    @field:NotBlank
+    val ort: String
+) {
+    @PostConstruct
+    fun postConstruct() {
+        // There is no try catch block around the operations on purpose!
+        // We want to throw here if this operations fail.
+        URL(basePath).toURI()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeGitlabApiProperties.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeGitlabApiProperties.kt
index f3a7c31c..c0010d37 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeGitlabApiProperties.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/OpenCodeGitlabApiProperties.kt
@@ -10,9 +10,9 @@ import java.net.URL
 @ConfigurationProperties(prefix = "opencode")
 @Validated
 data class OpenCodeGitlabApiProperties(
-    @NotBlank
+    @field:NotBlank
     val host: String,
-    @NotBlank
+    @field:NotBlank
     val accessToken: String
 ) {
     @PostConstruct
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/SecurityProperties.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/SecurityProperties.kt
index 56c94d25..4cb107e0 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/SecurityProperties.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/SecurityProperties.kt
@@ -3,16 +3,21 @@ package de.fraunhofer.iem.dataprovider.configuration.security
 import jakarta.validation.constraints.NotBlank
 import org.hibernate.validator.constraints.Length
 import org.springframework.boot.context.properties.ConfigurationProperties
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan
 import org.springframework.validation.annotation.Validated
 
 
 @ConfigurationProperties(prefix = "security")
+@ConfigurationPropertiesScan
 @Validated
 data class SecurityProperties(
-    @NotBlank
-    @Length(min = 20)
+    @field:NotBlank
+    @field:Length(min = 20)
     val adminPassword: String,
-    @NotBlank
-    @Length(min = 30)
+
+    @field:Length(min = 5)
+    val adminUsername: String,
+    @field:NotBlank
+    @field:Length(min = 30)
     val apiKey: String
 )
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebFluxConfiguration.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebFluxConfiguration.kt
index 7ae556fa..24e5bf22 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebFluxConfiguration.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebFluxConfiguration.kt
@@ -7,13 +7,11 @@ import org.springframework.web.reactive.config.WebFluxConfigurer
 
 @Configuration
 @EnableWebFlux
-class WebFluxConfiguration: WebFluxConfigurer
-{
-    override fun addCorsMappings(registry: CorsRegistry)
-    {
+class WebFluxConfiguration : WebFluxConfigurer {
+    override fun addCorsMappings(registry: CorsRegistry) {
         registry.addMapping("/**")
-                .allowedOrigins("*") // any host or put domain(s) here
-                .allowedMethods("*") // put the http verbs you want allow
-                .allowedHeaders("*") // put the http headers you want allow
+            .allowedOrigins("*") // any host or put domain(s) here
+            .allowedMethods("*") // put the http verbs you want allow
+            .allowedHeaders("*") // put the http headers you want allow
     }
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebSecurityConfiguration.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebSecurityConfiguration.kt
index e2669ce4..d3bda081 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebSecurityConfiguration.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/configuration/security/WebSecurityConfiguration.kt
@@ -15,7 +15,6 @@ import org.springframework.security.crypto.password.PasswordEncoder
 import org.springframework.security.web.server.SecurityWebFilterChain
 
 
-const val ADMIN_USERNAME: String = "admin"
 const val ADMIN_ROLE: String = "ADMIN"
 
 @Configuration
@@ -26,7 +25,7 @@ class SecurityConfiguration(val apiKeyFilter: ApiKeyFilter, private val security
     @Bean
     fun userDetailsService(): MapReactiveUserDetailsService {
         val user: UserDetails = User
-            .withUsername(ADMIN_USERNAME)
+            .withUsername(securityProperties.adminUsername)
             .password(passwordEncoder().encode(securityProperties.adminPassword))
             .roles(ADMIN_ROLE)
             .build()
@@ -46,12 +45,12 @@ class SecurityConfiguration(val apiKeyFilter: ApiKeyFilter, private val security
         return http {
             addFilterAt(apiKeyFilter, SecurityWebFiltersOrder.FIRST)
             authorizeExchange {
-                authorize(ApiPaths.KPI_ID, permitAll)
-                authorize(ApiPaths.KPI_ROOT_REPOSITORY, permitAll)
                 authorize(ApiPaths.REPOSITORY, permitAll)
                 authorize(ApiPaths.REPOSITORY_ID, permitAll)
-                authorize(ApiPaths.GITLAB_REPO_CHANGED, hasRole(ADMIN_ROLE))
-                authorize("${ApiPaths.DEBUG}/**", hasRole(ADMIN_ROLE))
+                authorize(ApiPaths.REPOSITORY_SCORE_CARD, permitAll)
+                authorize(ApiPaths.SCORE_CARD_BY_REPOSITORY_ID, permitAll)
+                authorize(ApiPaths.KPI_BY_REPOSITORY_ID, permitAll)
+                authorize(ApiPaths.OPENCODE_REPO_CHANGED, hasRole(ADMIN_ROLE))
                 authorize(anyExchange, denyAll)
             }
             httpBasic { }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/controller/MetricsController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/controller/MetricsController.kt
deleted file mode 100644
index 916caf83..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/controller/MetricsController.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.controller
-
-import de.fraunhofer.iem.dataprovider.configuration.ApiPaths
-import de.fraunhofer.iem.dataprovider.debug.dto.*
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.taskManager.TaskManager
-import de.fraunhofer.iem.dataprovider.taskManager.events.RecalculateAllKpisEvent
-import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
-import org.springframework.web.bind.annotation.GetMapping
-import org.springframework.web.bind.annotation.PathVariable
-import org.springframework.web.bind.annotation.PostMapping
-import org.springframework.web.bind.annotation.RestController
-
-@RestController
-class MetricsController(
-    private val toolRunService: ToolRunService,
-    private val taskManager: TaskManager
-) {
-
-    private val logger = getLogger(javaClass)
-
-    @GetMapping(ApiPaths.DEBUG_LATEST_RUN)
-    suspend fun getLatestToolRun(@PathVariable platform: PlatformEnum, @PathVariable id: Long): ToolResultsDto {
-        logger.info("Get latest tool runs for repo $id on platform $platform received.")
-        val toolResults = toolRunService.getLatestToolRunsForRepo(id, platform)
-        val repo = toolResults.first().repository!!
-        val repoDto = RepoDto(repo.name!!, repo.url!!)
-        val trDto = toolResults.map {
-            ToolRunDto(
-                it.findings.map { finding -> FindingDto(finding.message ?: "NO FINDING MESSAGE.") },
-                ToolDto(it.tool?.name!!, it.tool?.version!!),
-                it.createdAt!!
-            )
-        }
-        return ToolResultsDto(repoDto, trDto)
-    }
-
-    @PostMapping(ApiPaths.DEBUG_RECALCULATE_KPIS)
-    suspend fun recalculateAllKPIs() {
-        taskManager.addEvent(RecalculateAllKpisEvent)
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/FindingDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/FindingDto.kt
deleted file mode 100644
index 1481adb0..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/FindingDto.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.dto
-
-data class FindingDto(val message: String)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/RepoDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/RepoDto.kt
deleted file mode 100644
index 3320810a..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/RepoDto.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.dto
-
-data class RepoDto(val repoName: String, val repoUrl: String)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolDto.kt
deleted file mode 100644
index cd47f832..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolDto.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.dto
-
-data class ToolDto(val name: String, val version: String)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolResultsDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolResultsDto.kt
deleted file mode 100644
index 5ee1bd10..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolResultsDto.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.dto
-
-data class ToolResultsDto(val repo: RepoDto, val toolRuns: List<ToolRunDto>)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolRunDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolRunDto.kt
deleted file mode 100644
index 58309cb3..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/debug/dto/ToolRunDto.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.debug.dto
-
-import java.time.Instant
-
-data class ToolRunDto(val findings: List<FindingDto>, val tool: ToolDto, val createdAt: Instant)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/DependencyCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/DependencyCreateDto.kt
deleted file mode 100644
index 6a903a30..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/DependencyCreateDto.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.dto
-
-import de.fraunhofer.iem.dataprovider.dependency.entity.DependencyEntity
-
-data class DependencyCreateDto(
-    val name: String,
-    val vulnerabilities: MutableList<VulnerabilityCreateDto> = mutableListOf()
-) {
-
-    fun toDbObject(): DependencyEntity {
-        val dependency = DependencyEntity()
-        dependency.name = this.name
-
-        dependency.vulnerabilities = this.vulnerabilities.map { vulnerability ->
-            val vulnerabilityEntity = vulnerability.toDbObject()
-            vulnerabilityEntity.dependency = dependency
-            vulnerabilityEntity
-        }.toMutableSet()
-
-        return dependency
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityCreateDto.kt
deleted file mode 100644
index 6c510a79..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityCreateDto.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.dto
-
-import de.fraunhofer.iem.dataprovider.dependency.entity.VulnerabilityEntity
-
-data class VulnerabilityCreateDto(
-    val cveIdentifier: String,
-    val vulnerabilityScores: MutableList<VulnerabilityScoreCreateDto> = mutableListOf()
-) {
-    fun toDbObject(): VulnerabilityEntity {
-        val vulnerabilityEntity = VulnerabilityEntity()
-        vulnerabilityEntity.cveIdentifier = this.cveIdentifier
-
-        vulnerabilityEntity.vulnerabilityScores = this.vulnerabilityScores.map { score ->
-            val dbScore = score.toDbObject()
-            dbScore.vulnerability = vulnerabilityEntity
-            dbScore
-        }.toMutableSet()
-
-        return vulnerabilityEntity
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityScoreCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityScoreCreateDto.kt
deleted file mode 100644
index 88fa970f..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/dto/VulnerabilityScoreCreateDto.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.dto
-
-import de.fraunhofer.iem.dataprovider.dependency.entity.VulnerabilityScoreEntity
-import de.fraunhofer.iem.dataprovider.dependency.enumeration.VulnerabilityScoringSystemEnum
-
-data class VulnerabilityScoreCreateDto(
-    val severity: String,
-    val scoringSystem: VulnerabilityScoringSystemEnum
-) {
-    fun toDbObject(): VulnerabilityScoreEntity {
-        val vulnerabilityScoreEntity = VulnerabilityScoreEntity()
-        vulnerabilityScoreEntity.scoringSystem = this.scoringSystem
-        vulnerabilityScoreEntity.severity = this.severity
-        return vulnerabilityScoreEntity
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/DependencyEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/DependencyEntity.kt
deleted file mode 100644
index b90627a9..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/DependencyEntity.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.entity
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityScoreCreateDto
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "dependency")
-class DependencyEntity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @Column(name = "name", length = 600)
-    var name: String? = null
-
-    @OneToMany(
-        mappedBy = "dependency",
-        cascade = [CascadeType.ALL],
-        orphanRemoval = true
-    )
-    var vulnerabilities: MutableSet<VulnerabilityEntity> = mutableSetOf()
-
-    @ManyToMany(mappedBy = "dependencyEntities")
-    var repositories: MutableSet<RepositoryEntity> = mutableSetOf()
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as DependencyEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-
-    fun toDto(): DependencyCreateDto {
-        val dependencyCreateDto = DependencyCreateDto(this.name!!)
-        this.vulnerabilities.forEach { vulnerabilityEntity ->
-            val vulnerabilityCreateDto = VulnerabilityCreateDto(vulnerabilityEntity.cveIdentifier!!)
-
-            vulnerabilityEntity.vulnerabilityScores.forEach { scoreEntity ->
-                if (scoreEntity.severity != null && scoreEntity.scoringSystem != null) {
-                    vulnerabilityCreateDto.vulnerabilityScores.add(
-                        VulnerabilityScoreCreateDto(
-                            scoreEntity.severity!!,
-                            scoreEntity.scoringSystem!!
-                        )
-                    )
-                }
-            }
-
-            dependencyCreateDto.vulnerabilities.add(vulnerabilityCreateDto)
-        }
-        return dependencyCreateDto
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityEntity.kt
deleted file mode 100644
index d2924ad2..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityEntity.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.entity
-
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "vulnerability")
-class VulnerabilityEntity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @Column(name = "cve_identifier")
-    var cveIdentifier: String? = null
-
-    @ManyToOne
-    @JoinColumn(name = "dependency_id")
-    var dependency: DependencyEntity? = null
-
-    @OneToMany(
-        mappedBy = "vulnerability",
-        cascade = [CascadeType.ALL],
-        orphanRemoval = true
-    )
-    var vulnerabilityScores: MutableSet<VulnerabilityScoreEntity> = mutableSetOf()
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as VulnerabilityEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityScoreEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityScoreEntity.kt
deleted file mode 100644
index 2a3b81ce..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/entity/VulnerabilityScoreEntity.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.entity
-
-import de.fraunhofer.iem.dataprovider.dependency.enumeration.VulnerabilityScoringSystemEnum
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "vulnerability_score")
-class VulnerabilityScoreEntity {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @Column(name = "severity")
-    var severity: String? = null
-
-    @Enumerated(EnumType.STRING)
-    @Column(name = "scoring_system")
-    var scoringSystem: VulnerabilityScoringSystemEnum? = null
-
-    @ManyToOne
-    @JoinColumn(name = "vulnerability_id")
-    var vulnerability: VulnerabilityEntity? = null
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as VulnerabilityScoreEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/enumeration/VulnerabilityScoringSystemEnum.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/enumeration/VulnerabilityScoringSystemEnum.kt
deleted file mode 100644
index bd0cc430..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/enumeration/VulnerabilityScoringSystemEnum.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.enumeration
-
-enum class VulnerabilityScoringSystemEnum(val system: String) {
-    CVSSV3("CVSSV3"),
-    CVSSV3_1("CVSS:3.1");
-    //CVSSV3_1("cvssv3.1_qr");
-
-    companion object {
-        fun fromString(value: String): VulnerabilityScoringSystemEnum? {
-            return values().find { it.system.equals(value, ignoreCase = true) }
-        }
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/repository/DependencyRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/repository/DependencyRepository.kt
deleted file mode 100644
index bf92c2c1..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/repository/DependencyRepository.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.repository
-
-import de.fraunhofer.iem.dataprovider.dependency.entity.DependencyEntity
-import org.springframework.data.jpa.repository.JpaRepository
-import org.springframework.data.jpa.repository.Query
-import java.util.*
-
-interface DependencyRepository : JpaRepository<DependencyEntity, UUID> {
-
-
-    @Query("select d from DependencyEntity d inner join d.repositories repositories where repositories.id = ?1")
-    fun findByRepositories_Id(id: UUID): List<DependencyEntity>
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/service/DependencyService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/service/DependencyService.kt
deleted file mode 100644
index 47a78e5f..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/dependency/service/DependencyService.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.fraunhofer.iem.dataprovider.dependency.service
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.entity.DependencyEntity
-import de.fraunhofer.iem.dataprovider.dependency.repository.DependencyRepository
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import org.springframework.stereotype.Service
-import java.util.*
-
-@Service
-class DependencyService(private val dependencyRepository: DependencyRepository) {
-
-    private val logger = getLogger(javaClass)
-    fun save(dependencyEntity: DependencyEntity) {
-        dependencyRepository.save(dependencyEntity)
-    }
-
-    fun getDependenciesForRepository(repoId: UUID): List<DependencyCreateDto> {
-        // TODO: Refactor the type of dependencycreatdto
-        return dependencyRepository.findByRepositories_Id(repoId).map { it.toDto() }
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/controller/GitlabController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/controller/GitlabController.kt
index f6118858..1783dfe3 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/controller/GitlabController.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/controller/GitlabController.kt
@@ -2,26 +2,23 @@ package de.fraunhofer.iem.dataprovider.gitlab.controller
 
 import de.fraunhofer.iem.dataprovider.configuration.ApiPaths
 import de.fraunhofer.iem.dataprovider.gitlab.dto.RepositoryChangedDto
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
-import de.fraunhofer.iem.dataprovider.gitlab.service.GitlabService
 import de.fraunhofer.iem.dataprovider.logger.getLogger
+import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
 import org.springframework.web.bind.annotation.PostMapping
 import org.springframework.web.bind.annotation.RequestBody
 import org.springframework.web.bind.annotation.RestController
 
 
 @RestController
-class GitlabController(private val gitlabService: GitlabService) {
+class GitlabController(private val toolRunService: ToolRunService) {
 
     private val logger = getLogger(javaClass)
 
     // TODO: if the parsing of the request body fails we send a stack
     //  trace back this should be changed to a custom error.
-    @PostMapping(ApiPaths.GITLAB_REPO_CHANGED)
+    @PostMapping(ApiPaths.OPENCODE_REPO_CHANGED)
     suspend fun repoChanged(@RequestBody repositoryChangedDto: RepositoryChangedDto) {
-        logger.info("Repo changed POST request for ID ${repositoryChangedDto.repoId} on platform ${repositoryChangedDto.platform} received.")
-        when (repositoryChangedDto.platform) {
-            PlatformEnum.OPEN_CODE -> gitlabService.processRepositoryChanged(repositoryChangedDto.repoId)
-        }
+        logger.info("Repo changed POST request for ID ${repositoryChangedDto.projectId} received.")
+        toolRunService.createToolRunForRepository(repositoryChangedDto.projectId)
     }
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/dto/RepositoryChangedDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/dto/RepositoryChangedDto.kt
index 8535469f..91d1d927 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/dto/RepositoryChangedDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/dto/RepositoryChangedDto.kt
@@ -1,5 +1,4 @@
 package de.fraunhofer.iem.dataprovider.gitlab.dto
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
 
-data class RepositoryChangedDto(val repoId: Long, val platform: PlatformEnum)
\ No newline at end of file
+data class RepositoryChangedDto(val projectId: Long)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/enumeration/PlatformEnum.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/enumeration/PlatformEnum.kt
deleted file mode 100644
index fbc0b123..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/enumeration/PlatformEnum.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.gitlab.enumeration
-
-enum class PlatformEnum {
-    OPEN_CODE,
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/GitlabService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/GitlabService.kt
deleted file mode 100644
index 0916b4b1..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/GitlabService.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.fraunhofer.iem.dataprovider.gitlab.service
-
-import de.fraunhofer.iem.dataprovider.taskManager.TaskManager
-import de.fraunhofer.iem.dataprovider.taskManager.events.RepoChangedEvent
-import org.springframework.stereotype.Service
-
-
-@Service
-class GitlabService(
-        private val taskManager: TaskManager
-) {
-    suspend fun processRepositoryChanged(repoId: Long) {
-        taskManager.addEvent(RepoChangedEvent(repoId = repoId))
-    }
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
new file mode 100644
index 00000000..c32b8309
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
@@ -0,0 +1,87 @@
+package de.fraunhofer.iem.dataprovider.gitlab.service
+
+import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
+import de.fraunhofer.iem.dataprovider.logger.getLogger
+import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryCreateDto
+import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryDetailsDto
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.coroutineScope
+import org.gitlab4j.api.GitLabApi
+import org.gitlab4j.api.models.Commit
+import org.gitlab4j.api.models.Project
+import org.springframework.stereotype.Service
+
+
+/**
+ * This class wraps all usages of org.gitlab4j and transforms their data models
+ * into our internal data models.
+ */
+@Service
+class OpenCodeGitlabApi(openCodeGitlabConfiguration: OpenCodeGitlabApiProperties) {
+    private val logger = getLogger(javaClass)
+    private val gitlabApi: GitLabApi =
+        GitLabApi(openCodeGitlabConfiguration.host, openCodeGitlabConfiguration.accessToken)
+
+    /**
+     * Queries the gitlab project API at ${gitlabConfiguration.host} and returns a RepositoryCreateDto
+     */
+    fun getRepositoryInfo(repoId: Long): RepositoryCreateDto {
+        logger.info("Get repository info for repository id $repoId started")
+
+        val project = gitlabApi.projectApi.getProject(repoId)
+        val projectUri = project.httpUrlToRepo
+        val repoCreateDto = RepositoryCreateDto(project.path, projectUri, repoId)
+
+        logger.info("Get repository info $repoCreateDto finished successfully.")
+        return repoCreateDto
+    }
+
+    /**
+     * Queries gitlab project, commit, and repository API to create a RepositoryDetailsDto
+     */
+    suspend fun getRepositoryDetails(repoId: Long): RepositoryDetailsDto {
+        logger.info("Get repository details for repository id $repoId started")
+
+        val project = gitlabApi.projectApi.getProject(repoId)
+        // Note: We only take commits from the default branch
+        val commits = gitlabApi.commitsApi.getCommits(project.id, project.defaultBranch, ".")
+
+        val numberOfCommits = commits.count()
+        val numberOfSignedCommits = getNumberOfSignedCommits(repoId, commits)
+        val isDefaultBranchProtected = isDefaultBranchProtected(repoId, project)
+        val repoDetailsDto = RepositoryDetailsDto(
+            repoId,
+            numberOfCommits,
+            numberOfSignedCommits,
+            isDefaultBranchProtected
+        )
+
+        logger.info("Get repository details $repoDetailsDto finished successfully.")
+        return repoDetailsDto
+    }
+
+    private suspend fun getNumberOfSignedCommits(repoId: Long, commits: List<Commit>): Int = coroutineScope {
+
+        val deferreds = commits.map {
+            async(Dispatchers.IO) {
+                gitlabApi.commitsApi.getOptionalGpgSignature(repoId, it.id)
+            }
+        }
+
+        deferreds.awaitAll().count { !it.isEmpty }
+    }
+
+    // TODO: This should probably live somewhere else and encapsulate the logic
+    private fun isDefaultBranchProtected(repoId: Long, project: Project): Boolean {
+        return try {
+            val defaultBranchName = project.defaultBranch
+            val branch = gitlabApi.repositoryApi.getBranch(repoId, defaultBranchName)
+            branch.protected
+        } catch (e: Exception) {
+            // in theory, error probably happens if branch can't be found. In this case we default to false
+            false
+        }
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/controller/KPIController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/controller/KPIController.kt
deleted file mode 100644
index 666e411d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/controller/KPIController.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.controller
-
-import de.fraunhofer.iem.dataprovider.configuration.ApiPaths
-import de.fraunhofer.iem.dataprovider.kpi.dto.KPIResponseDto
-import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import org.springframework.web.bind.annotation.GetMapping
-import org.springframework.web.bind.annotation.PathVariable
-import org.springframework.web.bind.annotation.RestController
-import java.util.*
-
-@RestController
-class KPIController(private val kpiService: KPIService, private val repositoryService: RepositoryService) {
-
-    private val logger = getLogger(javaClass)
-
-    @GetMapping(ApiPaths.KPI_ID)
-    suspend fun getKPIByID(@PathVariable id: UUID): KPIResponseDto {
-        logger.info("Get KPI with id $id")
-        val kpiEntity = this.kpiService.findKPIById(id) ?: throw Exception("KPI with id $id can not be found")
-        return kpiEntity.toResultDto()
-    }
-
-    // TODO: Change this to something meaningful
-    @GetMapping(ApiPaths.KPI_ROOT_REPOSITORY)
-    suspend fun getRootKPIByRepositoryId(@PathVariable id: UUID): KPIResponseDto {
-        logger.info("Get root KPI from repository with id $id")
-        val repository = this.repositoryService.findRepoByID(id) ?: throw Exception("Repository can not be found")
-        val kpiEntity =
-            this.kpiService.findRootKPIByRepository(repository) ?: throw Exception("Root KPI can not be found")
-        return kpiEntity.toResultDto()
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIChildResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIChildResponseDto.kt
deleted file mode 100644
index 93514377..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIChildResponseDto.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.dto
-
-import java.util.*
-
-data class KPIChildResponseDto(val id: UUID, val weight: Double)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPICreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPICreateDto.kt
deleted file mode 100644
index 97dde045..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPICreateDto.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.dto
-
-import de.fraunhofer.iem.dataprovider.kpi.entity.KPIEntity
-import de.fraunhofer.iem.dataprovider.kpi.strategy.KPICalculationStrategy
-import java.sql.Timestamp
-import java.time.Instant
-
-
-class KPICreateDto(
-    val name: String,
-    val description: String,
-    val isRoot: Boolean,
-    private val calculationStrategy: KPICalculationStrategy,
-    private val displayScore: String? = null
-) {
-    val hierarchyEdges: MutableList<KPIHierarchyEdgeDto> = mutableListOf<KPIHierarchyEdgeDto>()
-    var value: Int? = null
-
-    fun calculateKPI() {
-        this.value = calculationStrategy.calculateKPI(this.hierarchyEdges)
-    }
-
-    fun addChildKPI(kpiCreateDto: KPICreateDto, weight: Double) {
-        val hierarchyEdge = KPIHierarchyEdgeDto(this, kpiCreateDto, weight)
-        this.hierarchyEdges.add(hierarchyEdge)
-    }
-
-    fun toDbObject(): KPIEntity {
-        val kpiEntity = KPIEntity()
-        kpiEntity.name = this.name
-        kpiEntity.score = this.value
-        kpiEntity.description = this.description
-        kpiEntity.isRoot = this.isRoot
-        kpiEntity.timestamp = Timestamp.from(Instant.now())
-        kpiEntity.displayScore = this.displayScore
-        return kpiEntity
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIHierarchyEdgeDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIHierarchyEdgeDto.kt
index 99d53fef..7ed7f2de 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIHierarchyEdgeDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIHierarchyEdgeDto.kt
@@ -1,3 +1,3 @@
 package de.fraunhofer.iem.dataprovider.kpi.dto
 
-data class KPIHierarchyEdgeDto (val from: KPICreateDto, val to: KPICreateDto, val weight: Double)
\ No newline at end of file
+data class KPIHierarchyEdgeDto(val from: KpiCalculationDto, val to: KpiCalculationDto, val weight: Double)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIResponseDto.kt
deleted file mode 100644
index 1114ca83..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPIResponseDto.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.dto
-
-import java.util.*
-
-data class KPIResponseDto(
-    val id: UUID,
-    val value: Int,
-    val name: String,
-    val description: String,
-    val isRoot: Boolean,
-    val displayValue: String? = null,
-    val children: List<KPIChildResponseDto>,
-    val repositoryId: UUID
-)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeChildResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeChildResponseDto.kt
new file mode 100644
index 00000000..f39efede
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeChildResponseDto.kt
@@ -0,0 +1,3 @@
+package de.fraunhofer.iem.dataprovider.kpi.dto
+
+data class KPITreeChildResponseDto(val kpi: KPITreeResponseDto, val weight: Double)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeResponseDto.kt
new file mode 100644
index 00000000..358a6d0b
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KPITreeResponseDto.kt
@@ -0,0 +1,13 @@
+package de.fraunhofer.iem.dataprovider.kpi.dto
+
+
+data class KPITreeResponseDto(
+    val value: Int,
+    val name: String,
+    val description: String,
+    val isRoot: Boolean = false,
+    val displayValue: String? = null,
+    val children: List<KPITreeChildResponseDto>,
+    val isEmpty: Boolean
+)
+
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
new file mode 100644
index 00000000..698040bd
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/KpiCalculationDto.kt
@@ -0,0 +1,63 @@
+package de.fraunhofer.iem.dataprovider.kpi.dto
+
+import de.fraunhofer.iem.dataprovider.kpi.enumeration.KpiKind
+import de.fraunhofer.iem.dataprovider.kpi.strategy.KPICalculationStrategy
+
+
+class KpiCalculationDto(
+    val kind: KpiKind,
+    private val calculationStrategy: KPICalculationStrategy? = null,
+    private var isEmpty: Boolean = true,
+    private var value: Int? = null
+) {
+    private val hierarchyEdges: MutableList<KPIHierarchyEdgeDto> = mutableListOf()
+
+    fun hasChildren(): Boolean {
+        return hierarchyEdges.isNotEmpty()
+    }
+
+    fun getHierarchyEdges(): List<KPIHierarchyEdgeDto> {
+        return hierarchyEdges.toList()
+    }
+
+    fun isEmpty(): Boolean {
+        return isEmpty
+    }
+
+    fun calculateKPI() {
+        if (calculationStrategy != null) {
+            try {
+                this.value = calculationStrategy.calculateKPI(this.hierarchyEdges)
+                this.isEmpty = false
+            } catch (exception: Exception) {
+                this.isEmpty = true
+                this.value = null
+            }
+        } else {
+            this.isEmpty = true
+        }
+    }
+
+    fun getValue(): Int {
+        if (value != null && !isEmpty) {
+            return value as Int
+        } else {
+            throw Exception("Value access for empty KPIs not allowed")
+        }
+    }
+
+    fun addChildKPI(kpiCreateDto: KpiCalculationDto, weight: Double) {
+        val hierarchyEdge = KPIHierarchyEdgeDto(this, kpiCreateDto, weight)
+        this.hierarchyEdges.add(hierarchyEdge)
+    }
+
+    fun toViewModel(): KPITreeResponseDto {
+
+        val children = this.hierarchyEdges.map {
+            val child = it.to.toViewModel()
+            KPITreeChildResponseDto(child, it.weight)
+        }
+
+        return this.kind.toViewModel(value = value ?: -1, children = children, isEmpty = isEmpty)
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/RawValueKpiCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/RawValueKpiCreateDto.kt
new file mode 100644
index 00000000..606788f4
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/dto/RawValueKpiCreateDto.kt
@@ -0,0 +1,18 @@
+package de.fraunhofer.iem.dataprovider.kpi.dto
+
+import de.fraunhofer.iem.dataprovider.kpi.entity.KPIEntity
+import de.fraunhofer.iem.dataprovider.kpi.enumeration.KpiKind
+import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
+import java.sql.Timestamp
+import java.time.Instant
+
+data class RawValueKpiCreateDto(val kind: KpiKind, val score: Int) {
+    fun toDbObject(repository: RepositoryEntity): KPIEntity {
+        return KPIEntity(
+            kind = this.kind,
+            score = this.score,
+            timestamp = Timestamp.from(Instant.now()),
+            repository = repository
+        )
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIEntity.kt
index 020c7904..ff18f18d 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIEntity.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIEntity.kt
@@ -1,7 +1,8 @@
 package de.fraunhofer.iem.dataprovider.kpi.entity
 
-import de.fraunhofer.iem.dataprovider.kpi.dto.KPIChildResponseDto
-import de.fraunhofer.iem.dataprovider.kpi.dto.KPIResponseDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.KpiCalculationDto
+import de.fraunhofer.iem.dataprovider.kpi.enumeration.KpiKind
+import de.fraunhofer.iem.dataprovider.kpi.strategy.RawValueKPICalculationStrategy
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 import jakarta.persistence.*
 import org.hibernate.annotations.JdbcTypeCode
@@ -11,60 +12,32 @@ import java.util.*
 
 @Entity
 @Table(name = "kpi")
-class KPIEntity {
+class KPIEntity(
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "id", nullable = false)
-    var id: UUID? = null
+    var id: UUID? = null,
 
-    @ManyToOne
+    @ManyToOne(optional = false)
     @JoinColumn(name = "repository_id")
-    var repository: RepositoryEntity? = null
+    val repository: RepositoryEntity,
 
-    @OneToMany(mappedBy = "from", cascade = [CascadeType.MERGE, CascadeType.REMOVE], orphanRemoval = true)
-    var hierarchyEdges: MutableSet<KPIHierarchyEdgeEntity> = mutableSetOf()
+    @Column(name = "score", nullable = false)
+    val score: Int,
 
-    @Column(name = "score")
-    var score: Int? = null
-
-    @Column(name = "display_score")
-    var displayScore: String? = null
-
-    @Column(name = "min")
-    var min: Int? = null
-
-    @Column(name = "max")
-    var max: Int? = null
-
-    @Column(name = "is_root")
-    var isRoot: Boolean? = null
-
-    @Column(name = "name")
-    var name: String? = null
-
-    @Column(name = "description", columnDefinition = "TEXT")
-    var description: String? = null
+    @Enumerated(EnumType.STRING)
+    var kind: KpiKind,
 
     @JdbcTypeCode(SqlTypes.TIMESTAMP)
     @Column(name = "timestamp")
     var timestamp: Timestamp? = null
+) {
 
-    fun toResultDto(): KPIResponseDto {
-        val childrenList = mutableListOf<KPIChildResponseDto>()
-        for (edge in this.hierarchyEdges) {
-            val id = edge.to!!.id!!
-            val weight = edge.weight!!
-            childrenList.add(KPIChildResponseDto(id, weight))
-        }
-        return KPIResponseDto(
-            this.id!!,
-            this.score!!,
-            this.name!!,
-            this.description!!,
-            this.isRoot!!,
-            this.displayScore,
-            childrenList,
-            this.repository!!.id!!
+    fun toCalculationDto(): KpiCalculationDto {
+        return KpiCalculationDto(
+            kind = this.kind,
+            calculationStrategy = RawValueKPICalculationStrategy(this.score),
+            isEmpty = false
         )
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIHierarchyEdgeEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIHierarchyEdgeEntity.kt
deleted file mode 100644
index 469ec830..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/entity/KPIHierarchyEdgeEntity.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.entity
-
-import jakarta.persistence.*
-import java.util.*
-
-@Entity
-@Table(name = "kpi_hierarchy_edge")
-class KPIHierarchyEdgeEntity {
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @ManyToOne(cascade = [CascadeType.MERGE])
-    @JoinColumn(name = "from_id")
-    var from: KPIEntity? = null
-
-    @ManyToOne(cascade = [CascadeType.MERGE])
-    @JoinColumn(name = "to_id")
-    var to: KPIEntity? = null
-
-    @Column(name = "weight")
-    var weight: Double? = null
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/enumeration/KpiKind.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/enumeration/KpiKind.kt
new file mode 100644
index 00000000..b080fe94
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/enumeration/KpiKind.kt
@@ -0,0 +1,215 @@
+package de.fraunhofer.iem.dataprovider.kpi.enumeration
+
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeChildResponseDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeResponseDto
+
+enum class KpiKind {
+    // Raw Value KPIs
+    CHECKED_IN_BINARIES {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Checked in Binary",
+                description = "Used to assess the compliance to the OpenCoDE platform guidelines in regards of not checking in binaries.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    NUMBER_OF_COMMITS {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Number of Commits",
+                description = "Total number of commits on the default branch of the repository.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    VULNERABILITY_SCORE {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            // TODO: in order to provide more detailed information here we need to query the ORT api
+            return KPITreeResponseDto(
+                value = value,
+                name = "Vulnerability Score",
+                description = "A vulnerability with this score was found in the projects dependencies. Further information are not disclosed here.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    NUMBER_OF_SIGNED_COMMITS {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Number of Signed Commits",
+                description = "Total number of signed and verified commits on the default branch of the repository.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    IS_DEFAULT_BRANCH_PROTECTED {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Default Branch Protection",
+                description = "Used to assess compliance with a standard development process. For this purpose, it is examined whether the standard development branch is protected against unintentional changes.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    SECRETS {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Secrets",
+                description = "Used to look for suspicious strings in the repository, which might indicate leaked passwords or other secrets.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    SAST_USAGE {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "SAST Usage",
+                description = "Used to approximate the usage of SAST tools during development.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+
+    // Calculated KPIs
+    SIGNED_COMMITS_RATIO {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Commit Signature Ratio",
+                description = "Used to assess compliance with a common and transparent development process. It is desirable that all commits are signed by their authors. Therefore, the ratio of signed commits to all commits is determined to calculate this metric.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    PROCESS_COMPLIANCE {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Process Compliance Score",
+                description = "Assesses the development process of the software provided. For this purpose, the development process traceable in the repository is compared with common development standards to enable an assessment.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    PROCESS_TRANSPARENCY {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Process Transparency Score",
+                description = "Assesses the transparency resp. traceability of the development process of the provided software for external parties. For this purpose, various analyzes are performed that assess the availability of information about the software development process within the repository.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    SECURITY {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Security Score",
+                description = "Assesses the security of the software provided. For this purpose, various security-relevant analyzes are carried out, which, among other things, check the external dependencies or the code for vulnerabilities.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+    MAXIMAL_VULNERABILITY {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Maximal Dependency Vulnerability Score",
+                description = "This score is calculated by the following formula: 100 - (max(CVSS score) * 10). Thus, a lower value indicates a more critical vulnerability.",
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    },
+
+    // ROOT
+    ROOT {
+        override fun toViewModel(
+            value: Int,
+            children: List<KPITreeChildResponseDto>,
+            isEmpty: Boolean
+        ): KPITreeResponseDto {
+            return KPITreeResponseDto(
+                value = value,
+                name = "Project Score",
+                description = "Assesses the project resp. the provided software in the aspects of maturity (based on quality, security and usability aspects) as well as development process.",
+                isRoot = true,
+                children = children,
+                isEmpty = isEmpty
+            )
+        }
+    };
+
+    abstract fun toViewModel(
+        value: Int,
+        children: List<KPITreeChildResponseDto>,
+        isEmpty: Boolean
+    ): KPITreeResponseDto
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIHierarchyEdgeRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIHierarchyEdgeRepository.kt
deleted file mode 100644
index a8339cbb..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIHierarchyEdgeRepository.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.fraunhofer.iem.dataprovider.kpi.repository
-
-import de.fraunhofer.iem.dataprovider.kpi.entity.KPIHierarchyEdgeEntity
-import org.springframework.data.jpa.repository.JpaRepository
-import java.util.*
-
-interface KPIHierarchyEdgeRepository : JpaRepository<KPIHierarchyEdgeEntity, UUID> {}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIRepository.kt
index f2029610..4b0d1de4 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIRepository.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/repository/KPIRepository.kt
@@ -6,6 +6,4 @@ import java.util.*
 
 interface KPIRepository : JpaRepository<KPIEntity, UUID> {
     fun findByRepository_Id(id: UUID): List<KPIEntity>
-
-    fun findFirstByRepository_IdAndIsRootTrue(id: UUID): Optional<KPIEntity>
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/service/KPIService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/service/KPIService.kt
index e114b512..eeb8899e 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/service/KPIService.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/service/KPIService.kt
@@ -1,29 +1,242 @@
 package de.fraunhofer.iem.dataprovider.kpi.service
 
-import de.fraunhofer.iem.dataprovider.kpi.dto.KPICreateDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeChildResponseDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeResponseDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.KpiCalculationDto
+import de.fraunhofer.iem.dataprovider.kpi.dto.RawValueKpiCreateDto
 import de.fraunhofer.iem.dataprovider.kpi.entity.KPIEntity
-import de.fraunhofer.iem.dataprovider.kpi.entity.KPIHierarchyEdgeEntity
-import de.fraunhofer.iem.dataprovider.kpi.repository.KPIHierarchyEdgeRepository
+import de.fraunhofer.iem.dataprovider.kpi.enumeration.KpiKind
 import de.fraunhofer.iem.dataprovider.kpi.repository.KPIRepository
+import de.fraunhofer.iem.dataprovider.kpi.strategy.AggregationKPICalculationStrategy
+import de.fraunhofer.iem.dataprovider.kpi.strategy.MaximumKPICalculationStrategy
+import de.fraunhofer.iem.dataprovider.kpi.strategy.RatioKPICalculationStrategy
 import de.fraunhofer.iem.dataprovider.logger.getLogger
+import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryDetailsDto
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-import org.springframework.data.repository.findByIdOrNull
+import de.fraunhofer.iem.dataprovider.tools.occmd.enumeration.Checks
+import de.fraunhofer.iem.dataprovider.tools.occmd.json.RawResultJson
+import de.fraunhofer.iem.dataprovider.tools.ort.dto.VulnerabilityDto
 import org.springframework.stereotype.Service
-import java.util.*
 
 @Service
-class KPIService(private val kpiRepository: KPIRepository, private val kpiHierarchyEdgeRepository: KPIHierarchyEdgeRepository) {
+class KPIService(
+    private val kpiRepository: KPIRepository,
+) {
 
     private val logger = getLogger(javaClass)
 
-    private fun calculateKPIsRecursively(kpi: KPICreateDto, visited: MutableSet<KPICreateDto>) {
+    fun removeKPIChildrenLowerThanSecondLevel(kpiTreeResponseDto: KPITreeResponseDto): KPITreeResponseDto {
+        val children: List<KPITreeChildResponseDto> = kpiTreeResponseDto.children.map {
+            KPITreeChildResponseDto(
+                KPITreeResponseDto(
+                    value = it.kpi.value,
+                    name = it.kpi.name,
+                    description = it.kpi.description,
+                    isRoot = it.kpi.isRoot,
+                    displayValue = it.kpi.displayValue,
+                    emptyList(),
+                    it.kpi.isEmpty,
+                ),
+                it.weight
+            )
+        }
+
+        return KPITreeResponseDto(
+            value = kpiTreeResponseDto.value,
+            name = kpiTreeResponseDto.name,
+            description = kpiTreeResponseDto.description,
+            isRoot = true,
+            displayValue = kpiTreeResponseDto.displayValue,
+            children = children,
+            isEmpty = kpiTreeResponseDto.isEmpty
+        )
+    }
+
+    /**
+     * This method calculates the OccmdCreateKpiDtos based upon the given tool results.
+     */
+    fun calculateOccmdKpis(rawOccmdResults: List<RawResultJson>): List<RawValueKpiCreateDto> {
+        val kpis = mutableListOf<RawValueKpiCreateDto>()
+
+        rawOccmdResults.forEach {
+            val check = Checks.fromString(it.check)
+            when (check) {
+                Checks.CheckedInBinaries ->
+                    kpis.add(
+                        RawValueKpiCreateDto(
+                            kind = KpiKind.CHECKED_IN_BINARIES,
+                            score = (it.score * 100).toInt()
+                        )
+                    )
+
+                Checks.SastUsageBasic ->
+                    kpis.add(
+                        RawValueKpiCreateDto(
+                            kind = KpiKind.SAST_USAGE,
+                            score = (it.score * 100).toInt()
+                        )
+                    )
+
+                Checks.Secrets ->
+                    kpis.add(
+                        RawValueKpiCreateDto(
+                            kind = KpiKind.SECRETS,
+                            score = (it.score * 10).toInt()
+                        )
+                    )
+
+                else ->
+                    logger.warn("Unknown result")
+            }
+        }
+
+        return kpis
+    }
+
+    fun calculateVulnerabilityKpis(vulnerabilityDtos: List<VulnerabilityDto>): List<RawValueKpiCreateDto> {
+        return vulnerabilityDtos.map {
+            RawValueKpiCreateDto(
+                kind = KpiKind.VULNERABILITY_SCORE,
+                score = (it.severity * 10).toInt()
+            )
+        }
+    }
+
+    /**
+     * Creates a named map of RepositoryCreateDtos, based upon the provided repository details.
+     * This method only returns raw KPIs.
+     */
+    fun calculateRepositoryDetailsKpis(repoDetailsDto: RepositoryDetailsDto): List<RawValueKpiCreateDto> {
+        return listOf(
+            RawValueKpiCreateDto(
+                kind = KpiKind.NUMBER_OF_COMMITS,
+                score = repoDetailsDto.numberOfCommits
+            ),
+            RawValueKpiCreateDto(
+                kind = KpiKind.NUMBER_OF_SIGNED_COMMITS,
+                score = repoDetailsDto.numberOfSignedCommits
+            ),
+            RawValueKpiCreateDto(
+                kind = KpiKind.IS_DEFAULT_BRANCH_PROTECTED,
+                score = if (repoDetailsDto.isDefaultBranchProtected) 100 else 0
+            )
+        )
+    }
+
+    private fun saveRawKpis(repository: RepositoryEntity, rawKpis: List<RawValueKpiCreateDto>) {
+        kpiRepository.saveAll(rawKpis.map { it.toDbObject(repository) })
+    }
+
+    fun getKpiTreeForRepository(repository: RepositoryEntity): KpiCalculationDto {
+        val rawValueKpis =
+            kpiRepository.findByRepository_Id(repository.id!!).mapNotNull { it.toCalculationDto() }.toMutableList()
+        val vulnerabilities = rawValueKpis.filter { it.kind == KpiKind.VULNERABILITY_SCORE }
+        rawValueKpis.toMutableList().removeAll(vulnerabilities)
+        val kpiMap = rawValueKpis.associateBy { it.kind }
+        val rootKpi = generateKPITree(kpiMap, vulnerabilities)
+        calculateKPIsRecursively(rootKpi)
+        return rootKpi
+    }
+
+    private fun generateKPITree(
+        rawValueKpis: Map<KpiKind, KpiCalculationDto> = emptyMap(),
+        vulnerabilityKpis: List<KpiCalculationDto> = emptyList()
+    ): KpiCalculationDto {
+
+        val signedCommitsRatioKPI =
+            KpiCalculationDto(
+                kind = KpiKind.SIGNED_COMMITS_RATIO,
+                calculationStrategy = RatioKPICalculationStrategy()
+            )
+
+        signedCommitsRatioKPI.addChildKPI(
+            rawValueKpis.getOrDefault(
+                KpiKind.NUMBER_OF_COMMITS,
+                KpiCalculationDto(kind = KpiKind.NUMBER_OF_COMMITS)
+            ), 1.0
+        )
+
+        signedCommitsRatioKPI.addChildKPI(
+            rawValueKpis.getOrDefault(
+                KpiKind.NUMBER_OF_SIGNED_COMMITS,
+                KpiCalculationDto(kind = KpiKind.NUMBER_OF_SIGNED_COMMITS)
+            ), 1.0
+        )
+
+
+        val processComplianceKPI = KpiCalculationDto(
+            kind = KpiKind.PROCESS_COMPLIANCE,
+            calculationStrategy = AggregationKPICalculationStrategy()
+        )
+
+
+        processComplianceKPI.addChildKPI(
+            rawValueKpis.getOrDefault(
+                KpiKind.IS_DEFAULT_BRANCH_PROTECTED,
+                KpiCalculationDto(kind = KpiKind.IS_DEFAULT_BRANCH_PROTECTED)
+            ), 0.5
+        )
+        processComplianceKPI.addChildKPI(signedCommitsRatioKPI, 0.5)
+
+        val processTransparencyKPI = KpiCalculationDto(
+            kind = KpiKind.PROCESS_TRANSPARENCY,
+            calculationStrategy = AggregationKPICalculationStrategy()
+        )
+
+        processTransparencyKPI.addChildKPI(signedCommitsRatioKPI, 1.0)
+
+        val securityKPI = KpiCalculationDto(
+            kind = KpiKind.SECURITY,
+            calculationStrategy = AggregationKPICalculationStrategy()
+        )
+
+        val maximalDependencyVulnerabilityKPI = KpiCalculationDto(
+            kind = KpiKind.MAXIMAL_VULNERABILITY,
+            calculationStrategy = MaximumKPICalculationStrategy()
+        )
+
+        vulnerabilityKpis.forEach { maximalDependencyVulnerabilityKPI.addChildKPI(it, 0.0) }
+
+
+        securityKPI.addChildKPI(
+            rawValueKpis.getOrDefault(
+                KpiKind.SECRETS,
+                KpiCalculationDto(kind = KpiKind.SECRETS)
+            ), 0.3
+        )
+
+        securityKPI.addChildKPI(
+            rawValueKpis.getOrDefault(
+                KpiKind.CHECKED_IN_BINARIES,
+                KpiCalculationDto(kind = KpiKind.CHECKED_IN_BINARIES)
+            ), 0.2
+        )
+
+        securityKPI.addChildKPI(maximalDependencyVulnerabilityKPI, 0.5)
+
+        val rootKPI = KpiCalculationDto(
+            kind = KpiKind.ROOT,
+            calculationStrategy = AggregationKPICalculationStrategy(),
+        )
+
+        rootKPI.addChildKPI(processTransparencyKPI, 0.25)
+        rootKPI.addChildKPI(processComplianceKPI, 0.25)
+        rootKPI.addChildKPI(securityKPI, 0.5)
+        return rootKPI
+    }
+
+
+    private fun calculateKPIsRecursively(
+        kpi: KpiCalculationDto,
+        visited: MutableSet<KpiCalculationDto> = mutableSetOf()
+    ) {
         // Check if the KPI has already been visited
         if (visited.contains(kpi)) {
             return
         }
 
         // Check if the KPI has child KPIs
-        if (kpi.hierarchyEdges.isEmpty()) {
+        if (!kpi.hasChildren()) {
             // Leaf node, calculate the KPI value
             kpi.calculateKPI()
             visited.add(kpi)
@@ -31,7 +244,7 @@ class KPIService(private val kpiRepository: KPIRepository, private val kpiHierar
         }
 
         // Recursively calculate child KPIs first
-        for (childEdge in kpi.hierarchyEdges) {
+        for (childEdge in kpi.getHierarchyEdges()) {
             calculateKPIsRecursively(childEdge.to, visited)
         }
 
@@ -40,71 +253,13 @@ class KPIService(private val kpiRepository: KPIRepository, private val kpiHierar
         visited.add(kpi)
     }
 
-    fun calculateKPIs(rootKPI: KPICreateDto) {
-        val visited: MutableSet<KPICreateDto> = mutableSetOf()
-        calculateKPIsRecursively(rootKPI, visited)
-    }
-
-    fun storeAndPurgeOld(repositoryEntity: RepositoryEntity, rootKPI: KPICreateDto) {
+    fun storeAndPurgeOld(repositoryEntity: RepositoryEntity, rawValueKpiCreateDtos: List<RawValueKpiCreateDto>) {
         purgeAllKPIs(repositoryEntity)
-        val kpiEntityDtoToEntityMapping: MutableMap<KPICreateDto, KPIEntity> = mutableMapOf()
-        storeKPI(repositoryEntity, rootKPI, kpiEntityDtoToEntityMapping)
-    }
-
-    private fun storeKPI(
-        repositoryEntity: RepositoryEntity,
-        kpi: KPICreateDto,
-        kpiEntityDtoToEntityMapping: MutableMap<KPICreateDto, KPIEntity>
-    ) {
-        // already visited
-        if (kpiEntityDtoToEntityMapping.contains(kpi)) {
-            return
-        }
-
-        if (kpi.hierarchyEdges.isEmpty()) {
-            // leaf node
-            val kpiEntity = kpi.toDbObject()
-            kpiEntity.repository = repositoryEntity
-
-            kpiEntityDtoToEntityMapping[kpi] = kpiEntity
-            kpiRepository.save(kpiEntity)
-            logger.info("Storing leaf node ${kpi.name}")
-            return
-        }
-
-        for (childEdge in kpi.hierarchyEdges) {
-            storeKPI(repositoryEntity, childEdge.to, kpiEntityDtoToEntityMapping)
-        }
-
-        val kpiEntity = kpi.toDbObject()
-        kpiEntity.repository = repositoryEntity
-        kpiEntityDtoToEntityMapping[kpi] = kpiEntity
-        kpiRepository.save(kpiEntity)
-        logger.info("Storing node ${kpi.name}")
-        for (hierarchyEdge in kpi.hierarchyEdges) {
-            val hierarchyEdgeEntity = KPIHierarchyEdgeEntity()
-            hierarchyEdgeEntity.from = kpiEntity
-            hierarchyEdgeEntity.to = kpiEntityDtoToEntityMapping[hierarchyEdge.to]
-            hierarchyEdgeEntity.weight = hierarchyEdge.weight
-            kpiHierarchyEdgeRepository.save(hierarchyEdgeEntity)
-            logger.info("Storing edge ${hierarchyEdge.weight}: From ${hierarchyEdge.from.name} to ${hierarchyEdge.to.name}")
-        }
+        saveRawKpis(repositoryEntity, rawValueKpiCreateDtos)
     }
 
     private fun purgeAllKPIs(repositoryEntity: RepositoryEntity) {
         val kpiEntities: List<KPIEntity> = kpiRepository.findByRepository_Id(repositoryEntity.id!!)
         kpiRepository.deleteAll(kpiEntities)
     }
-
-    fun findKPIById(id: UUID): KPIEntity? {
-        return kpiRepository.findByIdOrNull(id)
-    }
-
-    fun findRootKPIByRepository(repositoryEntity: RepositoryEntity): KPIEntity? {
-        val kpi = kpiRepository.findFirstByRepository_IdAndIsRootTrue(repositoryEntity.id!!)
-        if (kpi.isEmpty) {
-            return null
-        }
-        return kpi.get()
-    }
-}
\ No newline at end of file
+}
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 394778a6..b1f30bd5 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
@@ -2,15 +2,15 @@ package de.fraunhofer.iem.dataprovider.kpi.strategy
 
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPIHierarchyEdgeDto
 
-class AggregationKPICalculationStrategy: KPICalculationStrategy {
+class AggregationKPICalculationStrategy : KPICalculationStrategy {
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
-        var aggregate = 0;
+        var aggregate = 0
         for (child in children) {
-            if (child.to.value != null) {
-                val childValue = child.to.value!!;
-                aggregate += (childValue.toFloat() * child.weight).toInt();
+            if (!child.to.isEmpty()) {
+                val childValue = child.to.getValue()
+                aggregate += (childValue.toFloat() * child.weight).toInt()
             }
         }
-        return aggregate;
+        return aggregate
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/KPICalculationStrategy.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/KPICalculationStrategy.kt
index 1545b7f3..69f07bbf 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/KPICalculationStrategy.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/KPICalculationStrategy.kt
@@ -3,6 +3,5 @@ package de.fraunhofer.iem.dataprovider.kpi.strategy
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPIHierarchyEdgeDto
 
 interface KPICalculationStrategy {
-    fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int;
+    fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int
 }
-
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 3b1a251f..b0d62b90 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
@@ -1,18 +1,19 @@
 package de.fraunhofer.iem.dataprovider.kpi.strategy
+
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPIHierarchyEdgeDto
 
-class MaximumKPICalculationStrategy: KPICalculationStrategy {
+class MaximumKPICalculationStrategy : KPICalculationStrategy {
     // TODO: Currently it's tailored to the maximum dependency vulnerability score, this should change in the future
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
-        var maximum = 0;
+        var maximum = 0
         for (child in children) {
-            if (child.to.value != null) {
-                val childValue = child.to.value!!;
+            if (!child.to.isEmpty()) {
+                val childValue = child.to.getValue()
                 if (childValue > maximum) {
                     maximum = childValue
                 }
             }
         }
-        return (100 - (maximum));
+        return (100 - (maximum))
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RatioKPICalculationStrategy.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RatioKPICalculationStrategy.kt
index ae66607c..63622713 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RatioKPICalculationStrategy.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RatioKPICalculationStrategy.kt
@@ -2,16 +2,16 @@ package de.fraunhofer.iem.dataprovider.kpi.strategy
 
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPIHierarchyEdgeDto
 
-class RatioKPICalculationStrategy(): KPICalculationStrategy {
+class RatioKPICalculationStrategy : KPICalculationStrategy {
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
         if (children.size != 2) {
             throw Exception("Requires exactly two children")
         }
-        val firstValue = children[0].to.value
-        val secondValue = children[1].to.value
-        if (firstValue!! >= secondValue!!) {
-            return ((secondValue / firstValue) * 100).toInt();
+        val firstValue = children[0].to.getValue()
+        val secondValue = children[1].to.getValue()
+        if (firstValue >= secondValue) {
+            return ((secondValue.toDouble() / firstValue.toDouble()) * 100).toInt()
         }
-        return ((firstValue / secondValue) * 100).toInt();
+        return ((firstValue.toDouble() / secondValue.toDouble()) * 100).toInt()
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RawValueKPICalculationStrategy.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RawValueKPICalculationStrategy.kt
index d81b0fbc..5f477b02 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RawValueKPICalculationStrategy.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/kpi/strategy/RawValueKPICalculationStrategy.kt
@@ -2,8 +2,8 @@ package de.fraunhofer.iem.dataprovider.kpi.strategy
 
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPIHierarchyEdgeDto
 
-class RawValueKPICalculationStrategy(val value: Int): KPICalculationStrategy {
+class RawValueKPICalculationStrategy(private val value: Int) : KPICalculationStrategy {
     override fun calculateKPI(children: List<KPIHierarchyEdgeDto>): Int {
-        return this.value;
+        return this.value
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
index 90a9a434..15f1daca 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
@@ -1,8 +1,11 @@
 package de.fraunhofer.iem.dataprovider.repository.controller
 
 import de.fraunhofer.iem.dataprovider.configuration.ApiPaths
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeResponseDto
+import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
 import de.fraunhofer.iem.dataprovider.logger.getLogger
 import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryResponseDto
+import de.fraunhofer.iem.dataprovider.repository.dto.ScoreCardResponseDto
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
 import org.springframework.web.bind.annotation.GetMapping
@@ -11,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController
 import java.util.*
 
 @RestController
-class RepositoryController(private val repositoryService: RepositoryService) {
+class RepositoryController(private val repositoryService: RepositoryService, private val kpiService: KPIService) {
 
     private val logger = getLogger(javaClass)
 
@@ -21,22 +24,66 @@ class RepositoryController(private val repositoryService: RepositoryService) {
         return repositoryService.getAllRepositories().map { repositoryEntity: RepositoryEntity ->
             RepositoryResponseDto(
                 repositoryEntity.id!!,
-                repositoryEntity.name!!,
-                repositoryEntity.platform!!,
-                repositoryEntity.repoId!!
+                repositoryEntity.name,
+                repositoryEntity.repoId
             )
         }
     }
 
+    @GetMapping(ApiPaths.REPOSITORY_SCORE_CARD)
+    suspend fun getAllScoreCards(): List<ScoreCardResponseDto> {
+        logger.info("Get all repositories as score cards")
+        return repositoryService.getAllRepositories().map { repositoryEntity: RepositoryEntity ->
+            val rootKpi = kpiService.removeKPIChildrenLowerThanSecondLevel(
+                this.kpiService.getKpiTreeForRepository(repositoryEntity).toViewModel()
+            )
+
+            ScoreCardResponseDto(
+                RepositoryResponseDto(
+                    repositoryEntity.id!!,
+                    repositoryEntity.name,
+                    repositoryEntity.repoId
+                ),
+                rootKpi
+            )
+        }
+    }
+
+    @GetMapping(ApiPaths.SCORE_CARD_BY_REPOSITORY_ID)
+    suspend fun getScoreCardByRepositoryId(@PathVariable id: UUID): ScoreCardResponseDto {
+        logger.info("Get repository score card with id $id")
+        val repositoryEntity = this.repositoryService.findRepoByID(id) ?: throw Exception("Repository can not be found")
+        val rootKpi = kpiService.removeKPIChildrenLowerThanSecondLevel(
+            this.kpiService.getKpiTreeForRepository(repositoryEntity).toViewModel()
+        )
+
+
+        return ScoreCardResponseDto(
+            RepositoryResponseDto(
+                repositoryEntity.id!!,
+                repositoryEntity.name,
+                repositoryEntity.repoId
+            ),
+            rootKpi
+        )
+    }
+
     @GetMapping(ApiPaths.REPOSITORY_ID)
     suspend fun getRepositoryById(@PathVariable id: UUID): RepositoryResponseDto {
         logger.info("Get repository with id $id")
         val repositoryEntity = this.repositoryService.findRepoByID(id) ?: throw Exception("Repository can not be found")
         return RepositoryResponseDto(
             repositoryEntity.id!!,
-            repositoryEntity.name!!,
-            repositoryEntity.platform!!,
-            repositoryEntity.repoId!!
+            repositoryEntity.name,
+            repositoryEntity.repoId
         )
     }
-}
\ No newline at end of file
+
+    @GetMapping(ApiPaths.KPI_BY_REPOSITORY_ID)
+    suspend fun getKPIByRepositoryId(@PathVariable id: UUID): KPITreeResponseDto {
+        logger.info("Get KPI tree for repository id $id")
+        val repositoryEntity = this.repositoryService.findRepoByID(id) ?: throw Exception("Repository can not be found")
+        val rootKpi = this.kpiService.getKpiTreeForRepository(repositoryEntity)
+        return rootKpi.toViewModel()
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryCreateDto.kt
index c1d14851..29e12c39 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryCreateDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryCreateDto.kt
@@ -1,15 +1,13 @@
 package de.fraunhofer.iem.dataprovider.repository.dto
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 
-data class RepositoryCreateDto(val name: String, val uri: String, val id: Long, val platform: PlatformEnum) {
+data class RepositoryCreateDto(val name: String, val uri: String, val id: Long) {
     fun toDbObject(): RepositoryEntity {
-        val repo = RepositoryEntity()
-        repo.name = this.name
-        repo.repoId = this.id
-        repo.platform = this.platform
-        repo.url = this.uri
-        return repo
+        return RepositoryEntity(
+            name = this.name,
+            repoId = this.id,
+            url = this.uri
+        )
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsCreateDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsCreateDto.kt
deleted file mode 100644
index ccf5235f..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsCreateDto.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.fraunhofer.iem.dataprovider.repository.dto
-
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryDetailsEntity
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-
-data class RepositoryDetailsCreateDto(
-    val repositoryEntity: RepositoryEntity,
-    val numberOfCommits: Int,
-    val numberOfSignedCommits: Int,
-    val isDefaultBranchProtected: Boolean
-) {
-    fun toDbObject(): RepositoryDetailsEntity {
-        val repositoryDetailsEntity = RepositoryDetailsEntity()
-        repositoryDetailsEntity.repository = this.repositoryEntity
-        repositoryDetailsEntity.numberOfCommits = this.numberOfCommits
-        repositoryDetailsEntity.numberOfSignedCommits = this.numberOfSignedCommits
-        repositoryDetailsEntity.isDefaultBranchProtected = this.isDefaultBranchProtected
-        return repositoryDetailsEntity
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsDto.kt
new file mode 100644
index 00000000..0b876c99
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryDetailsDto.kt
@@ -0,0 +1,8 @@
+package de.fraunhofer.iem.dataprovider.repository.dto
+
+data class RepositoryDetailsDto(
+    val repoId: Long,
+    val numberOfCommits: Int,
+    val numberOfSignedCommits: Int,
+    val isDefaultBranchProtected: Boolean
+)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryResponseDto.kt
index 9cf5e829..827e0402 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryResponseDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/RepositoryResponseDto.kt
@@ -1,6 +1,5 @@
 package de.fraunhofer.iem.dataprovider.repository.dto
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
 import java.util.*
 
-data class RepositoryResponseDto(val id: UUID, val name: String, val platform: PlatformEnum, val repositoryId: Long)
\ No newline at end of file
+data class RepositoryResponseDto(val id: UUID, val name: String, val repositoryId: Long)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ScoreCardResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ScoreCardResponseDto.kt
new file mode 100644
index 00000000..4fc7e80e
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ScoreCardResponseDto.kt
@@ -0,0 +1,8 @@
+package de.fraunhofer.iem.dataprovider.repository.dto
+
+import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeResponseDto
+
+data class ScoreCardResponseDto(
+    val repository: RepositoryResponseDto,
+    val kpis: KPITreeResponseDto?
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryDetailsEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryDetailsEntity.kt
deleted file mode 100644
index 2e236a09..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryDetailsEntity.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.fraunhofer.iem.dataprovider.repository.entity
-
-import jakarta.persistence.*
-import org.hibernate.annotations.CurrentTimestamp
-import org.hibernate.annotations.UpdateTimestamp
-import org.hibernate.generator.EventType
-import java.time.Instant
-import java.util.*
-
-@Entity
-@Table(name = "repository_details")
-class RepositoryDetailsEntity {
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    var repository: RepositoryEntity? = null
-
-    @Column(name = "number_of_commits")
-    var numberOfCommits: Int? = null
-
-    @Column(name = "number_of_signed_commits")
-    var numberOfSignedCommits: Int? = null
-
-    @Column(name = "is_default_branch_protected")
-    var isDefaultBranchProtected: Boolean? = null
-
-    @CurrentTimestamp(event = [EventType.INSERT])
-    var createdAt: Instant? = null
-
-    @UpdateTimestamp
-    var lastUpdatedAt: Instant? = null
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryEntity.kt
index b7ea2ec8..b9bd19ab 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryEntity.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/entity/RepositoryEntity.kt
@@ -1,8 +1,6 @@
 package de.fraunhofer.iem.dataprovider.repository.entity
 
-import de.fraunhofer.iem.dataprovider.dependency.entity.DependencyEntity
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
-import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity
+
 import de.fraunhofer.iem.dataprovider.toolRun.entity.ToolRunEntity
 import jakarta.persistence.*
 import org.hibernate.annotations.CurrentTimestamp
@@ -13,12 +11,12 @@ import java.util.*
 
 @Entity
 @Table(name = "repository")
-class RepositoryEntity {
+class RepositoryEntity(
 
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "id", nullable = false)
-    var id: UUID? = null
+    var id: UUID? = null,
 
     @OrderBy("last_updated_at DESC")
     @OneToMany(
@@ -26,50 +24,25 @@ class RepositoryEntity {
         cascade = [CascadeType.MERGE, CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.DETACH],
         orphanRemoval = true
     )
-    var toolRuns: MutableList<ToolRunEntity> = mutableListOf()
-
-    @Column(name = "name")
-    var name: String? = null
+    val toolRuns: MutableList<ToolRunEntity> = mutableListOf(),
 
-    @Column(name = "repo_id")
-    var repoId: Long? = null
+    @Column(name = "name", nullable = false)
+    val name: String,
 
-    @Enumerated
-    @Column(name = "platform")
-    var platform: PlatformEnum? = null
+    @Column(name = "repo_id", nullable = false)
+    val repoId: Long,
 
-    @Column(name = "url")
-    var url: String? = null
+    @Column(name = "url", nullable = false)
+    val url: String,
 
     @CurrentTimestamp(event = [EventType.INSERT])
-    var createdAt: Instant? = null
+    var createdAt: Instant? = null,
 
     @UpdateTimestamp
     var lastUpdatedAt: Instant? = null
-
-    @ManyToMany
-    @JoinTable(
-        name = "repository_tools",
-        joinColumns = [JoinColumn(name = "repository_id")],
-        inverseJoinColumns = [JoinColumn(name = "tools_id")]
-    )
-    var toolEntities: MutableSet<ToolEntity> = mutableSetOf()
-
-    @ManyToMany
-    @JoinTable(
-        name = "repository_dependencies",
-        joinColumns = [JoinColumn(name = "repository_id")],
-        inverseJoinColumns = [JoinColumn(name = "dependency_id")]
-    )
-    var dependencyEntities: MutableSet<DependencyEntity> = mutableSetOf()
-    fun addToolResults(toolRuns: Collection<ToolRunEntity>) {
-        toolRuns.forEach {
-            this.addToolResult(it)
-        }
-    }
+) {
 
     fun addToolResult(toolRun: ToolRunEntity) {
         toolRuns.add(toolRun)
-        toolRun.repository = this
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryDetailsRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryDetailsRepository.kt
deleted file mode 100644
index 49bd8945..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryDetailsRepository.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.fraunhofer.iem.dataprovider.repository.repository
-
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryDetailsEntity
-import org.springframework.data.jpa.repository.JpaRepository
-import java.util.*
-
-
-interface RepositoryDetailsRepository : JpaRepository<RepositoryDetailsEntity, UUID> {
-    fun findFirstByRepository_IdOrderByCreatedAtDesc(id: UUID): Optional<RepositoryDetailsEntity>
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryRepository.kt
index d6e1c9aa..1e45ffeb 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryRepository.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/repository/RepositoryRepository.kt
@@ -1,11 +1,9 @@
 package de.fraunhofer.iem.dataprovider.repository.repository
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 import org.springframework.data.jpa.repository.JpaRepository
 import java.util.*
 
 interface RepositoryRepository : JpaRepository<RepositoryEntity, UUID> {
-    fun findByRepoIdAndPlatform(repoId: Long, platform: PlatformEnum): RepositoryEntity?
-
+    fun findByRepoId(repoId: Long): RepositoryEntity?
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/service/RepositoryService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/service/RepositoryService.kt
index e854c502..0b19d1e5 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/service/RepositoryService.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/service/RepositoryService.kt
@@ -1,31 +1,39 @@
 package de.fraunhofer.iem.dataprovider.repository.service
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
+import de.fraunhofer.iem.dataprovider.gitlab.service.OpenCodeGitlabApi
 import de.fraunhofer.iem.dataprovider.logger.getLogger
 import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryCreateDto
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryDetailsCreateDto
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryDetailsEntity
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-import de.fraunhofer.iem.dataprovider.repository.repository.RepositoryDetailsRepository
 import de.fraunhofer.iem.dataprovider.repository.repository.RepositoryRepository
 import org.springframework.stereotype.Service
 import java.util.*
 
 @Service
 class RepositoryService(
-        private val repositoryRepository: RepositoryRepository,
-        private val repositoryDetailsRepository: RepositoryDetailsRepository
+    private val repositoryRepository: RepositoryRepository,
+    private val openCodeGitlabApi: OpenCodeGitlabApi
 ) {
     private val logger = getLogger(javaClass)
 
-    fun getRepoOrCreate(gitRepository: RepositoryCreateDto): RepositoryEntity {
-        var repo = repositoryRepository.findByRepoIdAndPlatform(gitRepository.id, gitRepository.platform)
+    /**
+     * Either creates or returns a repository entity based upon its
+     * opencode repository id.
+     */
+    fun getOrCreate(gitRepository: RepositoryCreateDto): RepositoryEntity {
+        var repo = repositoryRepository.findByRepoId(gitRepository.id)
         if (repo == null) {
             repo = repositoryRepository.save(gitRepository.toDbObject())
         }
         return repo
     }
 
+    /**
+     * Queries the gitlab api to get the repo name, url, and id.
+     */
+    fun getRepositoryInfo(repoId: Long): RepositoryCreateDto {
+        return openCodeGitlabApi.getRepositoryInfo(repoId)
+    }
+
     // TODO: We should decide if we want to return optionals (null if not found) or throw exceptions or ...
     // TODO: Must be consistent across all methods
     fun findRepoByID(id: UUID): RepositoryEntity? {
@@ -40,22 +48,6 @@ class RepositoryService(
         repositoryRepository.save(repo)
     }
 
-    fun findRepoByRepoIdAndPlatform(repoId: Long, platform: PlatformEnum): RepositoryEntity? {
-        return repositoryRepository.findByRepoIdAndPlatform(repoId, platform)
-    }
-
-    fun createRepositoryDetails(repositoryDetailsCreateDto: RepositoryDetailsCreateDto): RepositoryDetailsEntity {
-        return repositoryDetailsRepository.save(repositoryDetailsCreateDto.toDbObject())
-    }
-
-    fun getLatestRepositoryDetailsByRepositoryId(repositoryId: UUID): RepositoryDetailsEntity? {
-        val repositoryDetails = repositoryDetailsRepository.findFirstByRepository_IdOrderByCreatedAtDesc(repositoryId)
-        if (repositoryDetails.isEmpty) {
-            return null
-        }
-        return repositoryDetails.get()
-    }
-
     fun getAllRepositories(): List<RepositoryEntity> {
         return repositoryRepository.findAll()
     }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/GroupTaskManager.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/GroupTaskManager.kt
deleted file mode 100644
index 36893d6d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/GroupTaskManager.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager
-
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.GroupTasksDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.model.GroupTasks
-import java.util.*
-
-class GroupTaskManager(val responseChannel: suspend (event: Event) -> Unit) {
-
-    private val dependentEvents: MutableMap<UUID, GroupTasks> = mutableMapOf()
-
-    /**
-     * Adds new group of tasks
-     */
-    fun createTaskGroup(repositoryId: UUID): UUID {
-        val groupId = UUID.randomUUID()
-        dependentEvents[groupId] = GroupTasks(repositoryId)
-        return groupId
-    }
-
-    fun addTaskToGroup(groupId: UUID, taskId: UUID) {
-        dependentEvents[groupId]?.taskIds?.add(taskId)
-    }
-
-    /**
-     * Removes the finished task with the given ID from the internal task list for the
-     * group. If the whole task group is finished a group finished event is sent.
-     */
-    suspend fun taskInGroupFinished(groupId: UUID, taskId: UUID) {
-        val groupTasks = dependentEvents[groupId]
-        if (groupTasks != null) {
-            val taskGroupEmpty = removeTaskFromGroup(groupTasks, taskId)
-            if (taskGroupEmpty) {
-                removeGroup(groupId)
-                responseChannel(GroupTasksDoneEvent(groupTasks.repositoryId))
-            }
-        }
-    }
-
-    private fun removeTaskFromGroup(groupTasks: GroupTasks, taskId: UUID): Boolean {
-        groupTasks.taskIds.remove(taskId)
-        return groupTasks.taskIds.isEmpty()
-    }
-
-    private fun removeGroup(groupId: UUID) {
-        dependentEvents.remove(groupId)
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/TaskManager.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/TaskManager.kt
deleted file mode 100644
index c5e6cec8..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/TaskManager.kt
+++ /dev/null
@@ -1,196 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager
-
-import de.fraunhofer.iem.dataprovider.configuration.DirectoryPathsProperties
-import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
-import de.fraunhofer.iem.dataprovider.dependency.service.DependencyService
-import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.taskManager.events.*
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery.CloneGitTask
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery.GetGitlabProjectTask
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery.GetRepositoryDetailsTask
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.kpiCalculation.MetricsTask
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.OrtApiTask
-import de.fraunhofer.iem.dataprovider.tool.service.ToolService
-import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
-import jakarta.annotation.PostConstruct
-import jakarta.annotation.PreDestroy
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.launch
-import org.springframework.stereotype.Component
-
-
-/**
- * The Task Manager takes tasks and distributes them to
- * underlying workers. Internally it uses a channel
- * to manage incoming tasks.
- */
-@Component
-class TaskManager(
-    private val directoryPathsProperties: DirectoryPathsProperties,
-    private val openCodeGitlabConfiguration: OpenCodeGitlabApiProperties,
-    private val toolRunService: ToolRunService,
-    private val toolService: ToolService,
-    private val repositoryService: RepositoryService,
-    private val kpiService: KPIService,
-    private val dependencyService: DependencyService
-) {
-
-    // The used default dispatcher is ok for CPU-bound workloads. However,
-    // if they block for a long time it's better to use a custom thread
-    // pool solution.
-    private val worker = Worker("Worker")
-
-    // Should be used for long-running tasks, which DON'T use CPU power and
-    // are non-blocking
-    private val ioWorker = Worker("IO-Worker", CoroutineScope(Dispatchers.IO))
-    // Should be used for long-running CPU heavy tasks, which potentially block.
-    // private val customWorker = getCustomThreadpoolWorker()
-
-    private val mainScope = CoroutineScope(Dispatchers.Default)
-    private val channel: Channel<Event> = Channel()
-
-    suspend fun addEvent(event: Event) {
-        channel.send(event)
-    }
-
-    @PostConstruct
-    private fun start() {
-        mainScope.launch {
-            for (task in channel) {
-                onReceive(task)
-            }
-        }
-    }
-
-    @PreDestroy
-    fun close() {
-        channel.close()
-        worker.close()
-        ioWorker.close()
-    }
-
-
-    private val logger = getLogger(javaClass)
-    private val groupTaskManager = GroupTaskManager(::onReceive)
-    suspend fun onReceive(event: Event) {
-        logger.info("[${Thread.currentThread().name}] add task called in Task Manager $event")
-
-        when (event) {
-            is RepoChangedEvent -> {
-                ioWorker.addTask(
-                    GetGitlabProjectTask(
-                        event.repoId,
-                        openCodeGitlabConfiguration,
-                        ::addEvent,
-                        repositoryService,
-                    )
-                )
-            }
-
-            is GetGitlabProjectDoneEvent -> {
-
-                ioWorker.addTask(
-                    CloneGitTask(
-                        event.gitRepository,
-                        event.repoId,
-                        ::addEvent,
-                        directoryPathsProperties.gitCloneTargetDirectory
-                    )
-                )
-            }
-
-            is GitCloneDoneEvent -> {
-
-                val groupId = groupTaskManager.createTaskGroup(event.repoId)
-
-//                    val occmdTask = OccmdTask(
-//                        event.outputDirectory,
-//                        config.toolResultsTargetDirectory,
-//                        openCodeGitlabConfiguration,
-//                        repositoryService,
-//                        ::addEvent,
-//                        event.repoId,
-//                        groupId,
-//                        toolRunService
-//                    )
-                ioWorker.addTask(
-                    OrtApiTask(
-                        ::addEvent,
-                        event.repoId,
-                        dependencyService,
-                        toolService,
-                        repositoryService
-                    )
-                )
-
-//                    groupTaskManager.addTaskToGroup(groupId, occmdTask.taskID)
-//
-//                    worker.addTask(occmdTask)
-            }
-
-            is GroupTaskDoneEvent -> {
-                logger.info("GroupTaskDoneEvent received")
-                groupTaskManager.taskInGroupFinished(event.groupId, event.taskId)
-            }
-
-            is GroupTasksDoneEvent -> {
-                logger.info("Adding repository details task")
-                worker.addTask(
-                    GetRepositoryDetailsTask(
-                        event.repoId,
-                        openCodeGitlabConfiguration,
-                        repositoryService,
-                        ::addEvent
-                    )
-                )
-            }
-
-            is GetRepositoryDetailsDoneEvent -> {
-                worker.addTask(
-                    MetricsTask(
-                        event.repoId,
-                        repositoryService,
-                        kpiService,
-                        ::addEvent,
-                        dependencyService,
-                        toolRunService
-                    )
-                )
-            }
-
-            is RecalculateAllKpisEvent -> {
-                repositoryService.getAllRepositories().forEach { repo ->
-                    worker.addTask(
-                        MetricsTask(
-                            repo.id!!,
-                            repositoryService,
-                            kpiService,
-                            ::addEvent,
-                            dependencyService,
-                            toolRunService
-                        )
-                    )
-                }
-            }
-
-            is TaskFailedEvent -> {
-                logger.info("task failed event received. ${event.throwable}")
-            }
-
-            is GroupTaskFailedEvent -> {
-                logger.info("Group task failed event received. ${event.throwable} ")
-                groupTaskManager.taskInGroupFinished(event.groupId, event.taskId)
-            }
-
-            else -> {
-                logger.info("Received event without special handling associated $event")
-            }
-        }
-        logger.info("[${Thread.currentThread().name}] add task finished in Task Manager $event")
-    }
-
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/Worker.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/Worker.kt
deleted file mode 100644
index cad933da..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/Worker.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager
-
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.ITask
-import kotlinx.coroutines.*
-import kotlinx.coroutines.channels.Channel
-import java.util.*
-
-
-interface IWorker {
-    /**
-     * Adds a new task to the worker's internal tasks channel.
-     */
-    suspend fun addTask(task: ITask)
-
-    // TODO: check if we can use autoclosable interface here.
-    /**
-     * Function used to close the underlying resources.
-     */
-    fun close()
-}
-
-
-fun getCustomThreadpoolWorker(): Worker {
-    val numCores = Runtime.getRuntime().availableProcessors()
-    // use a fixed size thread pool context with numCores threads
-    // TODO: Threadpool needs to be closed
-    @OptIn(DelicateCoroutinesApi::class)
-    val threadPoolContext = newFixedThreadPoolContext(numCores, "CustomThreadWorkerPool")
-    val coroutineScope = CoroutineScope(threadPoolContext)
-    return Worker("Custom-ThreadPool-Worker", coroutineScope)
-}
-
-/**
- * Abstract worker class used as a base for multithreaded worker.
- * It uses a fixed thread pool as a base for the coroutineScope.
- * The size of the thread pool is equal to the number of cores.
- */
-class Worker(
-    private val name: String,
-    private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.Default),
-    numberOfWorkers: Int = Runtime.getRuntime().availableProcessors()
-) : IWorker {
-
-    // TODO: this could be dangerous to give it unlimited memory
-    private val tasksChannel = Channel<ITask>(Channel.UNLIMITED)
-
-    // TODO: the task map should be cleared to reduce memory usage.
-    //  This needs to be triggered from outside a worker as soon as
-    //  all tasks related to the specific tasks are completed.
-    private val taskMap = HashMap<UUID, Pair<ITask, Job>>()
-    private val logger = getLogger(javaClass)
-
-    override suspend fun addTask(task: ITask) {
-        tasksChannel.send(task)
-    }
-
-    init {
-        logger.info("Starting $numberOfWorkers workers.")
-        repeat(numberOfWorkers) {
-            logger.info("[${Thread.currentThread().name}] launching coroutine in $name")
-            launchWorker(it)
-        }
-    }
-
-
-    /**
-     * Wrapper function to execute tasks provided through the channel.
-     * We use a dedicated number of coroutines to watch the tasks channel.
-     * Each coroutine starts a new coroutine to execute the task. This is
-     * done so that the outer coroutines are not blocked by the potentially
-     * very long-running inner task performed by executeTask.
-     */
-    private fun launchWorker(id: Int) = coroutineScope.launch {
-        for (task in tasksChannel) {
-            val job = coroutineScope.launch {
-                logger.debug("[{}] Processor #{}-{} received {}", Thread.currentThread().name, id, name, task)
-                // TODO: we need to check if we want to wrap this executeTask in a try-catch block
-                try {
-                    task.run()
-                } catch (e: Throwable) {
-                    logger.error("Exception during task execution occurred. TaskID: ${task.taskID}")
-                } finally {
-                    logger.debug("[{}] Processor #{}-{} finished {}", Thread.currentThread().name, id, name, task)
-                    taskMap.remove(task.taskID)
-                }
-
-            }
-            taskMap[task.taskID] = Pair(task, job)
-        }
-    }
-
-    override fun close() {
-        coroutineScope.launch {
-            tasksChannel.close()
-            for (job in coroutineContext[Job]!!.children) {
-                job.join()
-            }
-            logger.info("Worker $name has been closed")
-        }
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/Event.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/Event.kt
deleted file mode 100644
index 03f2eb5c..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/Event.kt
+++ /dev/null
@@ -1,2 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-sealed class Event
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetGitlabProjectDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetGitlabProjectDoneEvent.kt
deleted file mode 100644
index 7c13e525..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetGitlabProjectDoneEvent.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryCreateDto
-import java.util.*
-
-class GetGitlabProjectDoneEvent(taskId: UUID, val repoId: UUID, val gitRepository: RepositoryCreateDto) :
-    TaskDoneEvent(taskId = taskId)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetRepositoryDetailsDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetRepositoryDetailsDoneEvent.kt
deleted file mode 100644
index aac5ce2f..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GetRepositoryDetailsDoneEvent.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryDetailsEntity
-import java.util.*
-
-class GetRepositoryDetailsDoneEvent(
-    taskId: UUID,
-    val repoId: UUID,
-    val repositoryDetailsEntity: RepositoryDetailsEntity
-) : TaskDoneEvent(taskId = taskId)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GitCloneDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GitCloneDoneEvent.kt
deleted file mode 100644
index 9463dc1d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GitCloneDoneEvent.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-class GitCloneDoneEvent(taskId: UUID, val repoId: UUID, val outputDirectory: String) : TaskDoneEvent(taskId = taskId)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskDoneEvent.kt
deleted file mode 100644
index f9768b14..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskDoneEvent.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-class GroupTaskDoneEvent(
-    taskId: UUID,
-    val groupId: UUID,
-) : TaskDoneEvent(taskId = taskId)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskFailedEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskFailedEvent.kt
deleted file mode 100644
index 2c5846f1..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTaskFailedEvent.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-class GroupTaskFailedEvent(val throwable: Throwable, val groupId: UUID, val taskId: UUID) : Event()
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTasksDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTasksDoneEvent.kt
deleted file mode 100644
index decc2336..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/GroupTasksDoneEvent.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-class GroupTasksDoneEvent(val repoId: UUID) : Event()
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/OrtAnalyzerDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/OrtAnalyzerDoneEvent.kt
deleted file mode 100644
index 8a900b2c..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/OrtAnalyzerDoneEvent.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-class OrtAnalyzerDoneEvent(
-    val resultFileOutputDirectoryPath: String,
-    val repoId: UUID, val taskId: UUID, val groupID: UUID?
-) : Event()
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RecalculateAllKpisEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RecalculateAllKpisEvent.kt
deleted file mode 100644
index 0bfff349..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RecalculateAllKpisEvent.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-object RecalculateAllKpisEvent : Event()
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RepoChangedEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RepoChangedEvent.kt
deleted file mode 100644
index 6c2866b8..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/RepoChangedEvent.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-class RepoChangedEvent(val repoId: Long) : Event()
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskDoneEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskDoneEvent.kt
deleted file mode 100644
index e8f6d5b0..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskDoneEvent.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-import java.util.*
-
-open class TaskDoneEvent(val taskId: UUID) : Event()
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskFailedEvent.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskFailedEvent.kt
deleted file mode 100644
index 685ee420..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/events/TaskFailedEvent.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.events
-
-class TaskFailedEvent(val throwable: Throwable) : Event()
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/model/GroupTasks.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/model/GroupTasks.kt
deleted file mode 100644
index 46a067ed..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/model/GroupTasks.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.model
-
-import java.util.*
-
-data class GroupTasks(
-    val repositoryId: UUID,
-    val taskIds: MutableSet<UUID> = mutableSetOf()
-)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/Task.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/Task.kt
deleted file mode 100644
index 6505f898..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/Task.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks
-
-import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.GroupTaskFailedEvent
-import de.fraunhofer.iem.dataprovider.taskManager.events.TaskFailedEvent
-import java.util.*
-
-interface ITask {
-    suspend fun run()
-    val taskID: UUID
-}
-
-abstract class Task : ITask {
-    override val taskID: UUID = UUID.randomUUID()
-    protected open val groupID: UUID? = null
-
-    protected val logger = getLogger(javaClass)
-    protected abstract val responseChannel: suspend (event: Event) -> Unit
-    protected abstract suspend fun execute()
-
-    override suspend fun run() {
-        try {
-            execute()
-        } catch (e: Throwable) {
-            logger.error("Task execute failed.")
-            sendTaskFailedEvent(e)
-            throw e
-        }
-    }
-
-    protected suspend fun sendTaskFailedEvent(e: Throwable) {
-        if (groupID != null) {
-            responseChannel(GroupTaskFailedEvent(e, groupID!!, taskID))
-        } else {
-            responseChannel(TaskFailedEvent(e))
-        }
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/CloneGitTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/CloneGitTask.kt
deleted file mode 100644
index ed2ad694..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/CloneGitTask.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery
-
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryCreateDto
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.GitCloneDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import org.eclipse.jgit.api.Git
-import java.nio.file.Paths
-import java.util.*
-
-
-class CloneGitTask(
-    private val gitRepository: RepositoryCreateDto,
-    private val repoDbId: UUID,
-    override val responseChannel: suspend (task: Event) -> Unit,
-    private val outputPath: String,
-) : Task() {
-
-    override suspend fun execute() {
-
-        val outputDirName = "${gitRepository.name}-${taskID}"
-        val outputDirectory = Paths.get(outputPath, outputDirName)
-        logger.info("Cloning ${gitRepository.name} into $outputDirectory")
-
-        val git: Git = Git.cloneRepository()
-            .setURI(gitRepository.uri)
-            .setDirectory(outputDirectory.toFile())
-            .call()
-        git.close()
-
-        responseChannel(GitCloneDoneEvent(taskID, repoDbId, outputDirectory.toString()))
-        logger.info("Finished cloning ${gitRepository.name}")
-    }
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetGitlabProjectInfoTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetGitlabProjectInfoTask.kt
deleted file mode 100644
index c2b6a6c2..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetGitlabProjectInfoTask.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery
-
-import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryCreateDto
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.GetGitlabProjectDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import org.gitlab4j.api.GitLabApi
-
-
-class GetGitlabProjectTask(
-    private val repoId: Long,
-    private val gitlabConfiguration: OpenCodeGitlabApiProperties,
-    override val responseChannel: suspend (event: Event) -> Unit,
-    private val repositoryService: RepositoryService
-) : Task() {
-
-
-    private val gitlabApi: GitLabApi = GitLabApi(gitlabConfiguration.host, gitlabConfiguration.accessToken)
-
-    override suspend fun execute() {
-
-        val project = gitlabApi.projectApi.getProject(repoId)
-        logger.info(project.toString())
-        val projectUri = project.httpUrlToRepo
-
-        val gitRepository = RepositoryCreateDto(project.path, projectUri, repoId, PlatformEnum.OPEN_CODE)
-
-        val repo = repositoryService.getRepoOrCreate(gitRepository)
-
-        logger.info("Retrieved project ${project.path} and url $projectUri")
-
-        responseChannel(GetGitlabProjectDoneEvent(taskID, repo.id!!, gitRepository))
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetRepositoryDetailsTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetRepositoryDetailsTask.kt
deleted file mode 100644
index d1933947..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/dataQuery/GetRepositoryDetailsTask.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.dataQuery
-
-import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryDetailsCreateDto
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.GetRepositoryDetailsDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import org.gitlab4j.api.GitLabApi
-import org.gitlab4j.api.models.Commit
-import org.gitlab4j.api.models.Project
-import java.util.*
-
-class GetRepositoryDetailsTask(
-    private val repoId: UUID,
-    gitlabConfiguration: OpenCodeGitlabApiProperties,
-    private val repositoryService: RepositoryService,
-    override val responseChannel: suspend (event: Event) -> Unit,
-) : Task() {
-    private val gitlabApi: GitLabApi = GitLabApi(gitlabConfiguration.host, gitlabConfiguration.accessToken)
-
-    override suspend fun execute() {
-        val repositoryEntity = repositoryService.findRepoByID(repoId)
-        logger.info(repositoryEntity.toString())
-
-        if (repositoryEntity != null) {
-            val project = gitlabApi.projectApi.getProject(repositoryEntity.repoId)
-            // Note: We only take commits from the default branch
-            val commits = gitlabApi.commitsApi.getCommits(project.id, project.defaultBranch, ".")
-
-            val numberOfCommits = commits.count()
-            val numberOfSignedCommits = getNumberOfSignedCommits(repositoryEntity, commits)
-            val isDefaultBranchProtected = isDefaultBranchProtected(repositoryEntity, project)
-            val repositoryDetailsCreateDto = RepositoryDetailsCreateDto(
-                repositoryEntity,
-                numberOfCommits,
-                numberOfSignedCommits,
-                isDefaultBranchProtected
-            )
-
-            logger.info("Collected repository details from $repoId (${repositoryDetailsCreateDto}) successfully")
-            val repositoryDetailsEntity = repositoryService.createRepositoryDetails(repositoryDetailsCreateDto)
-            logger.info("Stored repository details for $repoId (${repositoryDetailsEntity}) successfully")
-
-            responseChannel(GetRepositoryDetailsDoneEvent(taskID, repoId, repositoryDetailsEntity))
-        } else {
-            logger.error("Repository $repoId can not be found in the database")
-        }
-    }
-
-    // TODO: This should probably live somewhere else and encapsulate the logic
-    private fun getNumberOfSignedCommits(repositoryEntity: RepositoryEntity, commits: List<Commit>): Int {
-        var numberOfSignedCommits = 0
-        for (commit in commits) {
-            val signature = gitlabApi.commitsApi.getOptionalGpgSignature(repositoryEntity.repoId, commit.id)
-            if (signature !== null) {
-                numberOfSignedCommits++
-            }
-        }
-        return numberOfSignedCommits
-    }
-
-    // TODO: This should probably live somewhere else and encapsulate the logic
-    private fun isDefaultBranchProtected(repositoryEntity: RepositoryEntity, project: Project): Boolean {
-        return try {
-            val defaultBranchName = project.defaultBranch
-            val branch = gitlabApi.repositoryApi.getBranch(repositoryEntity.repoId, defaultBranchName)
-            branch.protected
-        } catch (e: Exception) {
-            // in theory, error probably happens if branch can't be found. In this case we default to false
-            false
-        }
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/kpiCalculation/MetricsTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/kpiCalculation/MetricsTask.kt
deleted file mode 100644
index 72ae43c0..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/kpiCalculation/MetricsTask.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.kpiCalculation
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.service.DependencyService
-import de.fraunhofer.iem.dataprovider.kpi.dto.KPICreateDto
-import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
-import de.fraunhofer.iem.dataprovider.kpi.strategy.AggregationKPICalculationStrategy
-import de.fraunhofer.iem.dataprovider.kpi.strategy.MaximumKPICalculationStrategy
-import de.fraunhofer.iem.dataprovider.kpi.strategy.RatioKPICalculationStrategy
-import de.fraunhofer.iem.dataprovider.kpi.strategy.RawValueKPICalculationStrategy
-import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryDetailsEntity
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
-import java.util.*
-
-class MetricsTask(
-        val repoId: UUID,
-        private val repositoryService: RepositoryService,
-        private val kpiService: KPIService,
-        override val responseChannel: suspend (task: Event) -> Unit,
-        private val dependencyService: DependencyService,
-        private val toolRunService: ToolRunService,
-) : Task() {
-    override suspend fun execute() {
-        logger.info("Starting metrics task for repoId $repoId")
-        val repository = repositoryService.findRepoByID(repoId)
-        val repositoryDetails = repositoryService.getLatestRepositoryDetailsByRepositoryId(repoId)
-        if (repositoryDetails != null && repository != null) {
-            val rootKPI = generateKPITree(repositoryDetails)
-            kpiService.calculateKPIs(rootKPI)
-            kpiService.storeAndPurgeOld(repository, rootKPI)
-        }
-    }
-
-    private fun generateKPITree(repositoryDetailsEntity: RepositoryDetailsEntity): KPICreateDto {
-        val rootKPI = KPITreeFactory(repositoryDetailsEntity)
-
-        return rootKPI
-    }
-
-    private fun KPITreeFactory(repositoryDetailsEntity: RepositoryDetailsEntity): KPICreateDto {
-        // lowest level leaves
-        val numberOfCommitsKPI = KPICreateDto(
-            "Number of Commits",
-            "Total number of commits on the default branch of the repository.",
-            false,
-            RawValueKPICalculationStrategy(repositoryDetailsEntity.numberOfCommits!!)
-        )
-        val numberOfSignedCommitsKPI = KPICreateDto(
-            "Number of Signed Commits",
-            "Total number of signed and verified commits on the default branch of the repository.",
-            false,
-            RawValueKPICalculationStrategy(repositoryDetailsEntity.numberOfSignedCommits!!)
-        )
-        val isDefaultBranchProtectedKPI = KPICreateDto(
-            "Default Branch Protection",
-            "Used to assess compliance with a standard development process. For this purpose, it is examined whether the standard development branch is protected against unintentional changes.",
-            false,
-            RawValueKPICalculationStrategy(if (repositoryDetailsEntity.isDefaultBranchProtected == true) 100 else 0)
-        )
-
-        val signedCommitsRatioKPI =
-            KPICreateDto(
-                "Commit Signature Ratio",
-                "Used to assess compliance with a common and transparent development process. It is desirable that all commits are signed by their authors. Therefore, the ratio of signed commits to all commits is determined to calculate this metric.",
-                false,
-                RatioKPICalculationStrategy()
-            )
-        signedCommitsRatioKPI.addChildKPI(numberOfCommitsKPI, 1.0)
-        signedCommitsRatioKPI.addChildKPI(numberOfSignedCommitsKPI, 1.0)
-
-        // second level
-        // TODO: @Jan-Niclas Please add the dependency kpis to the security KPI
-        val securityKPI = KPICreateDto(
-            "Security Score",
-            "Assesses the security of the software provided. For this purpose, various security-relevant analyzes are carried out, which, among other things, check the external dependencies or the code for vulnerabilities.",
-            false,
-            AggregationKPICalculationStrategy()
-        )
-
-        val maximalDependencyVulnerabilityKPI = KPICreateDto(
-                "Maximal Dependency Vulnerability Score",
-                "This score is calculated by the following formula: 100 - (max(CVSS score) * 10). Thus, a lower value indicates a more critical vulnerability.",
-                false,
-                // This strategy is tied to this specific KPI. It calculates 100 - max(children). Children are already multiplied by 10
-                MaximumKPICalculationStrategy()
-        )
-
-        val dependencyDtos = dependencyService.getDependenciesForRepository(repoId);
-        // We change the structure to associate vulnerabilities with dependencies instead of dependencies with vulnerabilities
-        val vulnerabilitiesWithDependencies = restructureDependenciesAndVulnerabilities(dependencyDtos)
-        // For each vulnerability, we create a sub raw data kpi
-        addMaximalDependencyVulnerabilitySubKPIs(vulnerabilitiesWithDependencies, maximalDependencyVulnerabilityKPI)
-        securityKPI.addChildKPI(maximalDependencyVulnerabilityKPI, 0.5)
-
-        // TODO: There might be the case that there are no latest tool runs for this repository (would end up in an exception)
-        val latestToolRunOCCMD = toolRunService.getLatestToolRunsForRepo(repoId).filter { it.tool?.name == "OCCMD" }[0]
-        val secretKpi = KPICreateDto(
-            "Public Secrets",
-            "Score to indicate whether the repository contains secrets like passwords or api keys.",
-            false,
-            RawValueKPICalculationStrategy(if (latestToolRunOCCMD.findings.isEmpty()) 100 else 0)
-        )
-
-        securityKPI.addChildKPI(secretKpi, 0.5)
-
-        val processComplianceKPI = KPICreateDto(
-            "Process Compliance Score",
-            "Assesses the development process of the software provided. For this purpose, the development process traceable in the repository is compared with common development standards to enable an assessment.",
-            false,
-            AggregationKPICalculationStrategy()
-        )
-
-        val processTransparencyKPI = KPICreateDto(
-            "Process Transparency Score",
-            "Assesses the transparency resp. traceability of the development process of the provided software for external parties. For this purpose, various analyzes are performed that assess the availability of information about the software development process within the repository.",
-            false,
-            AggregationKPICalculationStrategy()
-        )
-        processComplianceKPI.addChildKPI(isDefaultBranchProtectedKPI, 0.5)
-        processComplianceKPI.addChildKPI(signedCommitsRatioKPI, 0.5)
-        processTransparencyKPI.addChildKPI(signedCommitsRatioKPI, 1.0)
-
-        val rootKPI = KPICreateDto(
-            "Project Score",
-            "Assesses the project resp. the provided software in the aspects of maturity (based on quality, security and usability aspects) as well as development process.",
-            true,
-            AggregationKPICalculationStrategy()
-        )
-        rootKPI.addChildKPI(processTransparencyKPI, 0.25)
-        rootKPI.addChildKPI(processComplianceKPI, 0.25)
-        rootKPI.addChildKPI(securityKPI, 0.5)
-        return rootKPI
-    }
-
-    private fun addMaximalDependencyVulnerabilitySubKPIs(vulnerabilitiesWithDependencies: HashMap<VulnerabilityCreateDto, MutableSet<String>>, maximalDependencyVulnerabilityKPI: KPICreateDto) {
-        // We iterate through the vulnerabilities and create a sub (raw data) kpi for each of them. Dependencies are displayed in the description
-        for ((vulnerability, dependencies) in vulnerabilitiesWithDependencies) {
-            maximalDependencyVulnerabilityKPI.addChildKPI(KPICreateDto(
-                    "Vulnerability " + vulnerability.cveIdentifier,
-                    "Affected packages: " + dependencies.joinToString(", "),
-                    false,
-                    // TODO: We multiply the CVSS score by 10 as the data structure can only hold integer values. This might be changed in the future.
-                    RawValueKPICalculationStrategy((vulnerability.vulnerabilityScores.first().severity.toDouble() * 10).toInt()),
-                    // TODO: Displayscore shows the real CVSS value, might not be needed if above TODO is resolved
-                    displayScore = vulnerability.vulnerabilityScores.first().severity
-            ), 0.0)
-        }
-    }
-
-    private fun restructureDependenciesAndVulnerabilities(dependencyDtos: List<DependencyCreateDto>): HashMap<VulnerabilityCreateDto, MutableSet<String>> {
-        val vulnerabilitiesWithDependencies = HashMap<VulnerabilityCreateDto, MutableSet<String>>()
-        // Switch structure around, so we can see which vulnerabilities are there and which dependencies are associated to them
-        for (dependencyDto in dependencyDtos) {
-            // Iterate through the list of vulnerabilities associated with each dependency
-            for (vulnerability in dependencyDto.vulnerabilities) {
-                // Check if the vulnerability is already present in the result map
-                // If not, add it with an empty list of dependencies
-                vulnerabilitiesWithDependencies.computeIfAbsent(vulnerability) { mutableSetOf() }
-                // Add the current dependency to the list of dependencies for the vulnerability
-                vulnerabilitiesWithDependencies[vulnerability]?.add(dependencyDto.name)
-            }
-        }
-        return vulnerabilitiesWithDependencies
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ToolProcessTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ToolProcessTask.kt
deleted file mode 100644
index 41330a1d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ToolProcessTask.kt
+++ /dev/null
@@ -1,78 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools
-
-import de.fraunhofer.iem.dataprovider.taskManager.events.GroupTaskDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.events.TaskDoneEvent
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import java.nio.file.Files
-import java.nio.file.Path
-import java.nio.file.Paths
-import java.util.*
-
-abstract class ToolProcessTask<ResultType> : Task() {
-    protected abstract val flags: Array<String>
-    protected abstract val resultFileOutputPath: Path
-    protected abstract val repoId: UUID
-    protected open val execPath: String = "/bin/sh"
-    protected abstract val outputDirectory: String
-
-    private val mainScope = CoroutineScope(Dispatchers.Default)
-    override suspend fun execute() {
-        withContext(Dispatchers.IO) {
-            Files.createDirectories(Paths.get(outputDirectory))
-        }
-
-        if (isExecutable(execPath)) {
-            val process = withContext(Dispatchers.IO) {
-                ProcessBuilder(execPath, *flags).start()
-            }
-
-
-            process.onExit().thenApply { p1 ->
-                mainScope.launch {
-                    handleProcessReturn(p1)
-                }
-            }
-        } else {
-            logger.warn("Given execPath is not an executable $execPath.")
-            // TODO: we should probably throw an exception here.
-        }
-    }
-
-    private fun isExecutable(filePath: String): Boolean {
-        val path = Paths.get(filePath)
-        return Files.isExecutable(path)
-    }
-
-    abstract suspend fun parseProcessResults(resultPath: Path): ResultType
-    abstract suspend fun storeResultsInDb(result: ResultType)
-    protected open suspend fun handleProcessReturn(p: Process) {
-        // TODO: check process exit codes. Current problem, if an analysis
-        //  has findings it might return an exit code != 0 even tho the process finished correctly
-        logger.info("Handle Process return in $javaClass")
-        try {
-            val results = parseProcessResults(resultFileOutputPath)
-            storeResultsInDb(results)
-            sendProcessTaskDoneEvent()
-        } catch (e: Throwable) {
-            sendTaskFailedEvent(e)
-        }
-        cleanUp()
-    }
-
-    protected open fun cleanUp() {}
-
-    private suspend fun sendProcessTaskDoneEvent() {
-
-        val event = if (groupID != null) {
-            GroupTaskDoneEvent(this.taskID, groupID!!)
-        } else {
-            TaskDoneEvent(this.taskID)
-        }
-
-        responseChannel(event)
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/OccmdTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/OccmdTask.kt
deleted file mode 100644
index 0e63c50d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/OccmdTask.kt
+++ /dev/null
@@ -1,89 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.occmd
-//
-//import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiConfiguration
-//import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-//import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-//import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.sarif.SarifTask
-//import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
-//import org.springframework.core.io.ClassPathResource
-//import org.springframework.core.io.Resource
-//import java.io.File
-//import java.nio.file.Files
-//import java.nio.file.Path
-//import java.nio.file.Paths
-//import java.util.*
-//
-//class OccmdTask(
-//    repositoryDirectoryPath: String,
-//    outputDirectoryPath: String,
-//    openCodeGitlabApiConfiguration: OpenCodeGitlabApiConfiguration,
-//    private val repositoryService: RepositoryService,
-//    override val responseChannel: suspend (task: Event) -> Unit,
-//    override val repoId: UUID,
-//    override val groupID: UUID? = null,
-//    override val toolRunService: ToolRunService
-//) : SarifTask() {
-//
-//    private val resource: Resource = ClassPathResource("scripts/occmd.sh")
-//
-//    override val outputDirectory: String = Paths.get(outputDirectoryPath, "occmd", taskID.toString()).toString()
-//    private val copiedRepositoryPath = Paths.get(outputDirectory, "copiedRepo")
-//    override val getSarif = ::getOccmdSarifFromFilePath
-//
-//    private val repositoryID = getRepositoryId(repoId)
-//    private val checkSecretPath =
-//        Paths.get(outputDirectory, "app", "notes", "opencode.d", "code", "resources", "checks", "secrets")
-//
-//    override val flags: Array<String> = arrayOf(
-//        resource.file.absolutePath,
-//        "--key",
-//        openCodeGitlabApiConfiguration.accessToken,
-//        "--username",
-//        "USERNAME", //TODO: Make sure is it required? if not delete otherwise dynamically take the username
-//        "--proj-path",
-//        copiedRepositoryPath.toString(),
-//        "--out-dir",
-//        Paths.get(outputDirectory, "app", "notes").toAbsolutePath().toString(),
-//        "--console-out-file",
-//        Paths.get(outputDirectory, "console.txt").toAbsolutePath().toString(),
-//        "--proj-id",
-//        repositoryID
-//    )
-//
-//    override val resultFileOutputPath: Path =
-//        Paths.get(checkSecretPath.toAbsolutePath().toString(), repositoryID, "DetectSecrets.baseline")
-//
-//    private fun getRepositoryId(repoId: UUID): String {
-//        val repoPlatformId = repositoryService.findRepoByID(repoId)?.repoId
-//            ?: throw NoSuchElementException("Repository with id $repoId was not found.")
-//        return repoPlatformId.toString()
-//    }
-//
-//
-//    private val dbRawPath = Paths.get(outputDirectory, "app", "notes", "opencode.d", "code", "db", "raw")
-//    private val blacklistPath = Paths.get(
-//        outputDirectory,
-//        "app",
-//        "notes",
-//        "opencode.d",
-//        "code",
-//        "resources",
-//        "checks",
-//        "checked_in_binaries",
-//        "blacklist"
-//    )
-//
-//    override fun cleanUp() {
-//        File(copiedRepositoryPath.toUri()).deleteRecursively()
-//    }
-//
-//    init {
-//        val repoFile = File(repositoryDirectoryPath)
-//        val copiedRepo = File(copiedRepositoryPath.toUri())
-//        repoFile.copyRecursively(copiedRepo)
-//
-//        Files.createDirectories(dbRawPath)
-//        Files.createDirectories(blacklistPath)
-//        Files.createDirectories(checkSecretPath)
-//    }
-//}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/json/sarif/OccmdSarif.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/json/sarif/OccmdSarif.kt
deleted file mode 100644
index 0c263fd0..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/occmd/json/sarif/OccmdSarif.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.occmd.json.sarif
-//
-//import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.occmd.json.raw.OccmdRaw
-//import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.sarif.json.*
-//import kotlinx.serialization.json.Json
-//import java.io.IOException
-//import java.nio.file.Path
-//
-//
-//fun getOccmdSarifFromFilePath(resultPath: Path): SarifJson {
-//    val resFile = resultPath.toFile()
-//    if (resFile.exists()) {
-//        val resString = resFile.readText()
-//        val json = Json { ignoreUnknownKeys = true}
-//        val occmdRaw = json.decodeFromString<OccmdRaw>(resString)
-//
-//        return occmdRawToSarif(occmdRaw)
-//    }
-//
-//    throw IOException("File not found / Path is no file.")
-//}
-//
-//private fun occmdRawToSarif(occmdRaw: OccmdRaw): SarifJson {
-//    val tool = SarifToolJson(SarifDriverJson(name = "OCCMD", fullName = "OCCMD", version = occmdRaw.version))
-//
-//    val results: MutableList<SarifResultJson> = mutableListOf()
-//
-//    for (elem in occmdRaw.results) {
-//        for (rawResult in elem.value) {
-//            val location = SarifLocationJson(
-//                SarifPhysicalLocationJson(
-//                    SarifArtifactLocationJson(rawResult.filename),
-//                    SarifRegionJson(startLine = rawResult.line_number)
-//                )
-//            )
-//
-//            val message = SarifMessageJson("hashed_string: ${rawResult.hashed_secret} and is_verified: ${rawResult.is_verified}")
-//            val result = SarifResultJson("warning", listOf(location), message, rawResult.type)
-//
-//            results.add(result)
-//        }
-//    }
-//
-//    val run = SarifRunJson(tool = tool, results = results)
-//    return SarifJson(listOf(run))
-//}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/OrtApiTask.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/OrtApiTask.kt
deleted file mode 100644
index 717cc990..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/OrtApiTask.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityScoreCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.entity.DependencyEntity
-import de.fraunhofer.iem.dataprovider.dependency.enumeration.VulnerabilityScoringSystemEnum
-import de.fraunhofer.iem.dataprovider.dependency.service.DependencyService
-import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.dto.OrtResultDto
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json.AdvisorResultJson
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json.OrtJson
-import de.fraunhofer.iem.dataprovider.tool.dto.CreateToolDto
-import de.fraunhofer.iem.dataprovider.tool.service.ToolService
-import io.ktor.client.*
-import io.ktor.client.call.*
-import io.ktor.client.engine.cio.*
-import io.ktor.client.plugins.contentnegotiation.*
-import io.ktor.client.request.*
-import io.ktor.client.statement.*
-import io.ktor.serialization.kotlinx.json.*
-import kotlinx.serialization.json.*
-import java.util.*
-
-class OrtApiTask(
-    override val responseChannel: suspend (event: Event) -> Unit,
-    val repoId: UUID,
-    private val dependencyService: DependencyService,
-    private val toolService: ToolService,
-    private val repositoryService: RepositoryService
-) : Task() {
-
-    override suspend fun execute() {
-
-        val client = HttpClient(CIO) {
-            install(ContentNegotiation) {
-                json(
-                    Json { ignoreUnknownKeys = true }
-                )
-            }
-        }
-
-        val response: HttpResponse = client.get("http://localhost:3000/ort")
-        val ortJson = response.body<OrtJson>()
-        println(response.status)
-        println(ortJson)
-        client.close()
-        val ortDto = ortJsonToDto(ortJson)
-        val dependencies = mutableListOf<DependencyCreateDto>()
-
-        ortDto.packages.forEach { p ->
-            if (p.nameAndVersion != null) {
-                dependencies.add(DependencyCreateDto(name = p.nameAndVersion))
-            }
-        }
-
-        ortDto.advisorResults.forEach { advisorResult ->
-
-            var dependency = dependencies.find { it.name == advisorResult.identifier }
-
-            if (dependency == null) {
-                dependency = DependencyCreateDto(advisorResult.identifier)
-                dependencies.add(dependency)
-            }
-            advisorResult.vulnerabilities.forEach { vulnerability ->
-                if (vulnerability.id != null) {
-
-                    val vulnerabilityScoreDtos =
-                        vulnerability.references.mapNotNull { ref ->
-                            if (ref.severity != null && ref.scoringSystem != null) {
-                                val scoringSystem = VulnerabilityScoringSystemEnum.fromString(ref.scoringSystem)
-                                scoringSystem?.let {
-                                    return@mapNotNull VulnerabilityScoreCreateDto(severity = ref.severity, it)
-                                }
-                            }
-                            return@mapNotNull null
-                        }
-                    val vulnerabilityDto =
-                        VulnerabilityCreateDto(vulnerability.id, vulnerabilityScoreDtos.toMutableList())
-                    dependency.vulnerabilities.add(vulnerabilityDto)
-                }
-            }
-        }
-
-        storeResultsInDb(dependencies)
-    }
-
-    private fun ortJsonToDto(rawJson: OrtJson): OrtResultDto {
-        val results = mutableListOf<AdvisorResultJson>()
-        val json = Json { ignoreUnknownKeys = true }
-        rawJson.advisor?.results?.advisorResults?.forEach { (key, value) ->
-            if (value is JsonArray) {
-                value.forEach { res ->
-                    if (res is JsonObject) {
-
-                        val flat = buildJsonObject {
-                            res.entries.forEach { (eKey, eValue) ->
-                                put(eKey, eValue)
-                            }
-                            put("identifier", key)
-                        }
-
-                        val advisorResult = json.decodeFromJsonElement<AdvisorResultJson>(flat)
-                        results.add(advisorResult)
-                    }
-                }
-            }
-        }
-        val packages = rawJson.analyzer?.result?.packages?.toList() ?: listOf()
-        return OrtResultDto(advisorResults = results, packages = packages)
-    }
-
-    // TODO: Requires a database purge / association with the tool run
-    private fun storeResultsInDb(result: List<DependencyCreateDto>) {
-        val dependencies = mutableListOf<DependencyEntity>()
-        result.forEach { dependency ->
-            val dependencyEntity = dependency.toDbObject()
-            dependencyService.save(dependencyEntity)
-            dependencies.add(dependencyEntity)
-        }
-        val tool = toolService.findOrCreateTool(CreateToolDto("ORT", "docker-snapshot"))
-        val repo = repositoryService.findRepoByID(repoId)
-        if (repo != null) {
-            repo.toolEntities.add(tool)
-            repo.dependencyEntities.addAll(dependencies)
-            repositoryService.save(repo)
-        }
-
-    }
-
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/dto/OrtResultDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/dto/OrtResultDto.kt
deleted file mode 100644
index 1177991d..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/dto/OrtResultDto.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.dto
-
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json.AdvisorResultJson
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json.PackageJson
-
-data class OrtResultDto(
-    val advisorResults: List<AdvisorResultJson> = listOf(),
-    val packages: List<PackageJson> = listOf()
-)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorInResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorInResultJson.kt
deleted file mode 100644
index 2e4b568e..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorInResultJson.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class AdvisorInResultJson(
-    @SerialName("capabilities")
-    val capabilities: List<String?>?,
-    @SerialName("name")
-    val name: String?
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorJson.kt
deleted file mode 100644
index c959a032..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorJson.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class AdvisorJson(
-    @SerialName("results")
-    val results: ResultsJson?
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorResultJson.kt
deleted file mode 100644
index f3ba9261..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AdvisorResultJson.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class AdvisorResultJson(
-    @SerialName("identifier")
-    val identifier: String,
-    @SerialName("advisor")
-    val advisor: AdvisorInResultJson?,
-    @SerialName("summary")
-    val summary: SummaryJson?,
-    @SerialName("vulnerabilities")
-    val vulnerabilities: MutableList<VulnerabilityJson> = mutableListOf()
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerJson.kt
deleted file mode 100644
index 686079a8..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerJson.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class AnalyzerJson(
-    @SerialName("result")
-    val result: AnalyzerResultJson?
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerResultJson.kt
deleted file mode 100644
index 2cce1ca7..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/AnalyzerResultJson.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class AnalyzerResultJson(
-    @SerialName("packages")
-    val packages: Array<PackageJson>
-) {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (javaClass != other?.javaClass) return false
-
-        other as AnalyzerResultJson
-
-        return packages.contentEquals(other.packages)
-    }
-
-    override fun hashCode(): Int {
-        return packages.contentHashCode()
-    }
-}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/IssueJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/IssueJson.kt
deleted file mode 100644
index 836842b7..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/IssueJson.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class IssueJson(
-    @SerialName("message")
-    val message: String?,
-    @SerialName("severity")
-    val severity: String?,
-    @SerialName("source")
-    val source: String?,
-    @SerialName("timestamp")
-    val timestamp: String?
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/OrtJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/OrtJson.kt
deleted file mode 100644
index 4f674d66..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/OrtJson.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class OrtJson(
-    @SerialName("advisor")
-    val advisor: AdvisorJson?,
-    @SerialName("analyzer")
-    val analyzer: AnalyzerJson?
-    // analyzer -> result -> packages[] -> id
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/PackageJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/PackageJson.kt
deleted file mode 100644
index 1503819e..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/PackageJson.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class PackageJson(
-    @SerialName("id")
-    val nameAndVersion: String?,
-)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ResultsJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ResultsJson.kt
deleted file mode 100644
index de2e7e62..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ResultsJson.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.JsonObject
-
-@Serializable
-data class ResultsJson(
-    @SerialName("advisor_results")
-    val advisorResults: JsonObject
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/SummaryJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/SummaryJson.kt
deleted file mode 100644
index 69720465..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/SummaryJson.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class SummaryJson(
-    @SerialName("end_time")
-    val endTime: String?,
-    @SerialName("issues")
-    val issues: List<IssueJson?>? = listOf(),
-    @SerialName("start_time")
-    val startTime: String?
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/VulnerabilityJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/VulnerabilityJson.kt
deleted file mode 100644
index 7d9b4cb5..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/VulnerabilityJson.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
-
-
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class VulnerabilityJson(
-    @SerialName("id")
-    val id: String?,
-    @SerialName("references")
-    val references: List<ReferenceJson> = listOf()
-)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/dto/CreateToolDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/dto/CreateToolDto.kt
index 61cb3d0b..d6c0ff87 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/dto/CreateToolDto.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/dto/CreateToolDto.kt
@@ -2,11 +2,8 @@ package de.fraunhofer.iem.dataprovider.tool.dto
 
 import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity
 
-data class CreateToolDto(val name: String, val version: String) {
+data class CreateToolDto(val name: String) {
     fun asDbObject(): ToolEntity {
-        val toolEntity = ToolEntity()
-        toolEntity.name = this.name
-        toolEntity.version = this.version
-        return toolEntity
+        return ToolEntity(name = this.name)
     }
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/RuleEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/RuleEntity.kt
deleted file mode 100644
index 4daceab7..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/entity/RuleEntity.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.fraunhofer.iem.dataprovider.tool.entity
-
-import de.fraunhofer.iem.dataprovider.toolRun.entity.FindingEntity
-import de.fraunhofer.iem.dataprovider.toolRun.entity.ToolRunEntity
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "rule")
-class RuleEntity {
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-
-    @Column(name = "tool_rule_id")
-    var toolRuleId: String? = null
-
-    @Column(name = "short_description", columnDefinition = "TEXT")
-    var shortDescription: String? = null
-
-    @OneToMany(
-        mappedBy = "rule",
-        cascade = [CascadeType.MERGE, CascadeType.REFRESH, CascadeType.REFRESH, CascadeType.DETACH],
-        orphanRemoval = true
-    )
-    var findings: MutableSet<FindingEntity> = mutableSetOf()
-
-    @ManyToOne
-    var toolRun: ToolRunEntity? = null
-
-    fun addFindings(findingEntities: Collection<FindingEntity>) {
-        findingEntities.forEach {
-            this.addFinding(it)
-        }
-    }
-
-    fun addFinding(findingEntity: FindingEntity) {
-        findings.add(findingEntity)
-        findingEntity.rule = this
-    }
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as RuleEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
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 fe0f1e2e..7575fdb4 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
@@ -2,31 +2,19 @@ package de.fraunhofer.iem.dataprovider.tool.entity
 
 import jakarta.persistence.*
 import org.hibernate.Hibernate
-import org.hibernate.annotations.CurrentTimestamp
-import org.hibernate.annotations.UpdateTimestamp
-import org.hibernate.generator.EventType
-import java.time.Instant
 import java.util.*
 
 @Entity
 @Table(name = "tool")
-class ToolEntity {
+class ToolEntity(
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "id", nullable = false)
-    var id: UUID? = null
+    var id: UUID? = null,
 
-    @Column(name = "name", length = 500)
-    var name: String? = null
-
-    @Column(name = "version")
-    var version: String? = null
-
-    @CurrentTimestamp(event = [EventType.INSERT])
-    var createdAt: Instant? = null
-
-    @UpdateTimestamp
-    var lastUpdatedAt: Instant? = null
+    @Column(name = "name", length = 500, nullable = false)
+    val name: String,
+) {
 
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
@@ -37,4 +25,4 @@ class ToolEntity {
     }
 
     override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/RuleRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/RuleRepository.kt
deleted file mode 100644
index ddeb5ce8..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/RuleRepository.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package de.fraunhofer.iem.dataprovider.tool.repository
-
-import de.fraunhofer.iem.dataprovider.tool.entity.RuleEntity
-import org.springframework.data.jpa.repository.JpaRepository
-import java.util.*
-
-interface RuleRepository : JpaRepository<RuleEntity, UUID> {
-
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/ToolRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/ToolRepository.kt
index b5760546..4b896d83 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/ToolRepository.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/repository/ToolRepository.kt
@@ -5,8 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository
 import java.util.*
 
 interface ToolRepository : JpaRepository<ToolEntity, UUID> {
-    fun findByNameIgnoreCaseAndVersionIgnoreCase(
-        name: String?,
-        version: String?
+    fun findByNameIgnoreCase(
+        name: String?
     ): ToolEntity?
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/RuleService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/RuleService.kt
deleted file mode 100644
index c0921e0b..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tool/service/RuleService.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package de.fraunhofer.iem.dataprovider.tool.service
-
-import de.fraunhofer.iem.dataprovider.tool.entity.RuleEntity
-import de.fraunhofer.iem.dataprovider.tool.repository.RuleRepository
-import org.springframework.stereotype.Service
-
-@Service
-class RuleService(
-    private val ruleRepository: RuleRepository,
-) {
-
-    fun saveRules(ruleEntities: List<RuleEntity>) {
-        ruleRepository.saveAll(ruleEntities)
-    }
-
-}
\ No newline at end of file
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 f13b4d17..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,15 +10,10 @@ class ToolService(
     private val toolRepository: ToolRepository,
 ) {
 
-    fun save(tool: ToolEntity) {
-        toolRepository.save(tool)
-    }
-
     fun findOrCreateTool(tool: CreateToolDto): ToolEntity {
-        return toolRepository.findByNameIgnoreCaseAndVersionIgnoreCase(
-            tool.name,
-            tool.version
+        return toolRepository.findByNameIgnoreCase(
+            tool.name
         )
             ?: toolRepository.save(tool.asDbObject())
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/FindingEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/FindingEntity.kt
deleted file mode 100644
index 067351fb..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/FindingEntity.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package de.fraunhofer.iem.dataprovider.toolRun.entity
-
-import de.fraunhofer.iem.dataprovider.tool.entity.RuleEntity
-import de.fraunhofer.iem.dataprovider.toolRun.enumeration.LevelEnum
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "finding")
-class FindingEntity {
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @ManyToOne
-    var rule: RuleEntity? = null
-
-    @OneToMany(mappedBy = "findingEntity", cascade = [CascadeType.ALL], orphanRemoval = true)
-    var locationEntities: MutableSet<LocationEntity> = mutableSetOf()
-
-    fun addLocations(locationEntities: Collection<LocationEntity>) {
-        locationEntities.forEach {
-            this.addLocation(it)
-        }
-    }
-
-    fun addLocation(locationEntity: LocationEntity) {
-        locationEntities.add(locationEntity)
-        locationEntity.findingEntity = this
-    }
-
-    @Enumerated
-    @Column(name = "level")
-    var level: LevelEnum? = null
-
-    @Column(name = "message", columnDefinition = "TEXT")
-    var message: String? = null
-
-    @ManyToOne
-    var toolRun: ToolRunEntity? = null
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as FindingEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/LocationEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/LocationEntity.kt
deleted file mode 100644
index 83b98a72..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/LocationEntity.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package de.fraunhofer.iem.dataprovider.toolRun.entity
-
-import jakarta.persistence.*
-import org.hibernate.Hibernate
-import java.util.*
-
-@Entity
-@Table(name = "location")
-class LocationEntity {
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @ManyToOne
-    var findingEntity: FindingEntity? = null
-
-    @Column(name = "artifact_location", columnDefinition = "TEXT")
-    var artifactLocation: String? = null
-
-    @Column(name = "end_column")
-    var endColumn: Int? = null
-
-    @Column(name = "end_line")
-    var endLine: Int? = null
-
-    @Column(name = "start_column")
-    var startColumn: Int? = null
-
-    @Column(name = "start_line")
-    var startLine: Int? = null
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other == null || Hibernate.getClass(this) != Hibernate.getClass(other)) return false
-        other as LocationEntity
-
-        return id != null && id == other.id
-    }
-
-    override fun hashCode(): Int = javaClass.hashCode()
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/ToolRunEntity.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/ToolRunEntity.kt
index 3ac96817..56f86848 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/ToolRunEntity.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/entity/ToolRunEntity.kt
@@ -1,7 +1,6 @@
 package de.fraunhofer.iem.dataprovider.toolRun.entity
 
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
-import de.fraunhofer.iem.dataprovider.tool.entity.RuleEntity
 import de.fraunhofer.iem.dataprovider.tool.entity.ToolEntity
 import jakarta.persistence.*
 import org.hibernate.annotations.CurrentTimestamp
@@ -14,55 +13,26 @@ import java.util.*
 
 @Entity
 @Table(name = "tool_run")
-class ToolRunEntity {
+class ToolRunEntity(
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "id", nullable = false)
-    var id: UUID? = null
-
-    @OneToOne(orphanRemoval = true)
-    @JoinColumn(name = "tool_id")
-    var tool: ToolEntity? = null
+    var id: UUID? = null,
 
     @ManyToOne(fetch = FetchType.EAGER)
-    var repository: RepositoryEntity? = null
+    val repository: RepositoryEntity,
 
-    @OneToMany(
-        mappedBy = "toolRun",
-        orphanRemoval = true
+    @ManyToMany
+    @JoinTable(
+        name = "tool_run_tool_entities",
+        joinColumns = [JoinColumn(name = "tool_run_entity_id")],
+        inverseJoinColumns = [JoinColumn(name = "tool_entities_id")]
     )
-    var rules: MutableSet<RuleEntity> = mutableSetOf()
-
-    @OneToMany(mappedBy = "toolRun", cascade = [CascadeType.ALL], orphanRemoval = true)
-    var findings: MutableSet<FindingEntity> = mutableSetOf()
+    val toolEntities: MutableSet<ToolEntity> = mutableSetOf(),
 
     @CurrentTimestamp(event = [EventType.INSERT])
-    var createdAt: Instant? = null
+    var createdAt: Instant? = null,
 
     @UpdateTimestamp
     var lastUpdatedAt: Instant? = null
-
-
-    fun addFindings(findingEntities: Collection<FindingEntity>) {
-        findingEntities.forEach {
-            this.addFinding(it)
-        }
-    }
-
-    fun addFinding(findingEntity: FindingEntity) {
-        findings.add(findingEntity)
-        findingEntity.toolRun = this
-    }
-
-    fun addRules(ruleEntities: Collection<RuleEntity>) {
-        ruleEntities.forEach {
-            this.addRule(it)
-        }
-    }
-
-    fun addRule(ruleEntity: RuleEntity) {
-        rules.add(ruleEntity)
-        ruleEntity.toolRun = this
-    }
-}
-
+)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/enumeration/LevelEnum.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/enumeration/LevelEnum.kt
deleted file mode 100644
index af7065e9..00000000
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/enumeration/LevelEnum.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package de.fraunhofer.iem.dataprovider.toolRun.enumeration
-
-enum class LevelEnum {
-    Warning, Error, Note, None
-}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/repository/ToolRunRepository.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/repository/ToolRunRepository.kt
index 3d388b18..595ba0cf 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/repository/ToolRunRepository.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/toolRun/repository/ToolRunRepository.kt
@@ -4,6 +4,4 @@ import de.fraunhofer.iem.dataprovider.toolRun.entity.ToolRunEntity
 import org.springframework.data.jpa.repository.JpaRepository
 import java.util.*
 
-interface ToolRunRepository : JpaRepository<ToolRunEntity, UUID> {
-    fun findFirstByTool_IdAndRepository_IdOrderByCreatedAtDesc(id: UUID, id1: UUID): ToolRunEntity?
-}
+interface ToolRunRepository : JpaRepository<ToolRunEntity, UUID>
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 51670867..9347b1bf 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
@@ -1,89 +1,117 @@
 package de.fraunhofer.iem.dataprovider.toolRun.service
 
-import de.fraunhofer.iem.dataprovider.gitlab.enumeration.PlatformEnum
+import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
 import de.fraunhofer.iem.dataprovider.logger.getLogger
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.tool.service.RuleService
-import de.fraunhofer.iem.dataprovider.tool.service.ToolService
 import de.fraunhofer.iem.dataprovider.toolRun.entity.ToolRunEntity
 import de.fraunhofer.iem.dataprovider.toolRun.repository.ToolRunRepository
+import de.fraunhofer.iem.dataprovider.tools.gitlab.service.RepositoryDetailsService
+import de.fraunhofer.iem.dataprovider.tools.occmd.service.OccmdService
+import de.fraunhofer.iem.dataprovider.tools.ort.service.OrtService
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
 import org.springframework.stereotype.Service
-import java.util.*
 
 @Service
 class ToolRunService(
-    private val repositoryService: RepositoryService,
-    private val toolService: ToolService,
-    private val ruleService: RuleService,
     private val toolRunRepository: ToolRunRepository,
+    private val repositoryService: RepositoryService,
+    private val repositoryDetailsService: RepositoryDetailsService,
+    private val kpiService: KPIService,
+    private val ortService: OrtService,
+    private val occmdService: OccmdService
 ) {
 
+    private val defaultScope = CoroutineScope(Dispatchers.Default)
+    private val ioScope = CoroutineScope(Dispatchers.IO)
     private val logger = getLogger(javaClass)
 
-    fun getLatestToolRunsForRepo(repoId: Long, platform: PlatformEnum): List<ToolRunEntity> {
-        val repo = repositoryService.findRepoByRepoIdAndPlatform(repoId, platform)
-        if (repo !== null) {
-            return getLatestToolResultsForRepo(repo)
-        } else {
-            logger.warn("Requested repository doesn't exist.")
-        }
-        return emptyList()
-    }
+    /**
+     * Warning: Long running function!
+     *
+     * In this function we calculate the KPIs for the given project using information from the gitlab api.
+     * Therefore, we first create a repository and tool run object in the DB.
+     *
+     * Next, we asynchronously query the gitlab API and dedicated opencode tool APIs for further data.
+     * Based upon this data we calculate RAW KPIs.
+     *
+     * Once all API responses have been processes we create a KPI tree and store this to the DB.
+     *
+     * Lastly, we update the tool run with all tools, which provided results for the given repository,
+     * and store this to the DB.
+     */
+    suspend fun createToolRunForRepository(repoId: Long) = defaultScope.launch {
+
+        /**
+         * Create initial db models.
+         * If this fails we want the whole method to fail as we can't continue
+         * without the db models.
+         *
+         */
+        val toolRun = async(ioScope.coroutineContext) {
+            val repoDto = repositoryService.getRepositoryInfo(repoId)
+            val repo = repositoryService.getOrCreate(repoDto)
+            val tr = createToolRunForRepository(repo)
+            tr
+        }.await()
+
+        /**
+         * For all tools, we in parallel query the tool results API.
+         * If the tool has results, add the tool to the tool run
+         * and then calculate the raw KPI based on the results.
+         * When all tool APIs are processed we purge the old KPIs
+         * from the db and store the new results.
+         * Lastly, we update the tool run object with all tools,
+         * which returned results for this repository.
+         */
+        val apiJobs = listOf(
+            async {
+                val vulnerabilityDtos =
+                    ortService.getOrtResults(106) // in the dev setup we get results for repo id 106
+                if (vulnerabilityDtos.isNotEmpty()) {
+                    toolRun.toolEntities.add(ortService.toolEntity)
+                }
+                kpiService.calculateVulnerabilityKpis(vulnerabilityDtos)
+            },
 
-    fun getLatestToolRunsForRepo(repoId: UUID): List<ToolRunEntity> {
-        val repo = repositoryService.findRepoByID(repoId)
-        if (repo !== null) {
-            return getLatestToolResultsForRepo(repo)
-        } else {
-            logger.warn("Requested repository doesn't exist.")
+            async {
+                val repoDetailsDto = repositoryDetailsService.getRepositoryDetails(repoId)
+                toolRun.toolEntities.add(repositoryDetailsService.toolEntity)
+                kpiService.calculateRepositoryDetailsKpis(repoDetailsDto)
+            },
+
+            async {
+                val rawOccmdResults = occmdService.runOccmd(repoId, toolRun.repository.url)
+                if (rawOccmdResults.isNotEmpty()) {
+                    toolRun.toolEntities.add(occmdService.toolEntity)
+                }
+                kpiService.calculateOccmdKpis(rawOccmdResults)
+            }
+        )
+
+        val kpis = apiJobs.mapNotNull {
+            try {
+                it.await()
+            } catch (exception: Exception) {
+                null
+            }
+        }.flatten()
+
+        if (kpis.isNotEmpty()) {
+            kpiService.storeAndPurgeOld(toolRun.repository, kpis)
+            saveToolRunEntity(toolRun)
         }
-        return emptyList()
     }
 
+    fun createToolRunForRepository(repo: RepositoryEntity): ToolRunEntity {
+        val tr = ToolRunEntity(repository = repo)
+        return toolRunRepository.save(tr)
+    }
 
-    private fun getLatestToolResultsForRepo(repo: RepositoryEntity): List<ToolRunEntity> {
-        return repo.toolEntities.mapNotNull { tool ->
-            toolRunRepository.findFirstByTool_IdAndRepository_IdOrderByCreatedAtDesc(tool.id!!, repo.id!!)
-        }
+    fun saveToolRunEntity(toolRunEntity: ToolRunEntity): ToolRunEntity {
+        return toolRunRepository.save(toolRunEntity)
     }
-//
-//    // TODO: this func should be a suspend fun. We can achieve this by
-//    //  wrapping the db return types in flux, mono, or futures
-//    fun createToolRunFromSarif(sarifJson: SarifJson, repoId: UUID) {
-//
-//        val repo = repositoryService.findRepoByID(repoId)
-//
-//        sarifJson.runs.forEach { run ->
-//
-//            val tool = toolService.findOrCreateTool(run.tool)
-//            val rules = run.tool.driver.rules.map { it.asDbObject() }
-//            ruleService.saveRules(rules)
-//
-//            val toolResults = run.results.map { sarifResult ->
-//                val tr = sarifResult.asDbObject()
-//                // link rules to results
-//                rules.filter { it.toolRuleId == sarifResult.ruleId }
-//                    .forEach { it.addFinding(tr) }
-//                tr
-//            }
-//
-//
-//            val toolRun = run.asDbObject()
-//            toolRun.tool = tool
-//            toolRun.addRules(rules)
-//            toolRun.addFindings(toolResults)
-//
-//            val result = toolRunRepository.save(toolRun)
-//            toolService.save(tool)
-//
-//            if (repo != null) {
-//                if (!repo.toolEntities.contains(tool)) {
-//                    repo.toolEntities.add(tool)
-//                }
-//                repo.addToolResult(result)
-//                repositoryService.save(repo)
-//            }
-//        }
-//    }
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/gitlab/service/RepositoryDetailsService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/gitlab/service/RepositoryDetailsService.kt
new file mode 100644
index 00000000..6a3b5eb0
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/gitlab/service/RepositoryDetailsService.kt
@@ -0,0 +1,23 @@
+package de.fraunhofer.iem.dataprovider.tools.gitlab.service
+
+import de.fraunhofer.iem.dataprovider.gitlab.service.OpenCodeGitlabApi
+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, 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)
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/enumeration/Checks.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/enumeration/Checks.kt
new file mode 100644
index 00000000..635151c2
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/enumeration/Checks.kt
@@ -0,0 +1,11 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.enumeration
+
+enum class Checks(val checkName: String) {
+    SastUsageBasic("SastUsageBasic"), Secrets("Secrets"), CheckedInBinaries("CheckedInBinaries");
+
+    companion object {
+        fun fromString(value: String): Checks? {
+            return Checks.entries.find { it.checkName.equals(value, ignoreCase = true) }
+        }
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/RawResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/RawResultJson.kt
new file mode 100644
index 00000000..42bedf02
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/RawResultJson.kt
@@ -0,0 +1,21 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.json.JsonObject
+
+/**
+ * The result of an occmd check performed on an OpenCodDE project.
+ */
+@Serializable
+data class RawResultJson(
+    @SerialName("check")
+    val check: String,
+    @SerialName("id")
+    val id: Int,
+    @SerialName("results")
+    val results: JsonObject,
+    @SerialName("score")
+    val score: Double
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/SecretResultsJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/SecretResultsJson.kt
new file mode 100644
index 00000000..552bd343
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/SecretResultsJson.kt
@@ -0,0 +1,11 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class SecretResultsJson(
+    @SerialName("tool_secrets")
+    val toolSecrets: List<ToolSecretJson> = listOf()
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretJson.kt
new file mode 100644
index 00000000..2d4121dd
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretJson.kt
@@ -0,0 +1,13 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ToolSecretJson(
+    @SerialName("name")
+    val name: String,
+    @SerialName("secrets")
+    val secrets: List<String> = mutableListOf()
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretResultJson.kt
new file mode 100644
index 00000000..d803d1cd
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/json/ToolSecretResultJson.kt
@@ -0,0 +1,13 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ToolSecretResultJson(
+    @SerialName("name")
+    val name: String,
+    @SerialName("secrets")
+    val tool_secrets: List<ToolSecretJson> = listOf()
+)
\ No newline at end of file
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
new file mode 100644
index 00000000..e32a71e5
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/occmd/service/OccmdService.kt
@@ -0,0 +1,108 @@
+package de.fraunhofer.iem.dataprovider.tools.occmd.service
+
+import de.fraunhofer.iem.dataprovider.configuration.DirectoryPathsProperties
+import de.fraunhofer.iem.dataprovider.configuration.OpenCodeGitlabApiProperties
+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.json.RawResultJson
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.future.await
+import kotlinx.coroutines.withContext
+import kotlinx.serialization.json.Json
+import org.eclipse.jgit.api.Git
+import org.springframework.stereotype.Service
+import java.io.File
+import java.nio.file.Files.isExecutable
+import java.nio.file.Paths
+import java.util.*
+import kotlin.io.path.ExperimentalPathApi
+import kotlin.io.path.deleteRecursively
+
+@Service
+class OccmdService(
+    private val dirProperties: DirectoryPathsProperties,
+    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)
+    }
+
+
+    /**
+     * First, we clone the given repository from opencode to the path provided in the application.properties.
+     *
+     * Next, we run the OCCMD tool in a separate process using Java's process builder.
+     *
+     * Lastly, after calculating the KPIs of the OCCMD tool run, we delete the cloned repository and return
+     * the DTOs.
+     */
+    @OptIn(ExperimentalPathApi::class)
+    suspend fun runOccmd(repoId: Long, repoUrl: String): List<RawResultJson> {
+        // clone repo
+        val outDir = Paths.get(dirProperties.gitCloneTargetDirectory, "$repoId-${Date().time}")
+        cloneGit(repoUrl, outDir.toFile())
+        // run tool
+        val rawOccmdResults = runOccmd(
+            dirProperties.occmdPath, arrayOf(
+                outDir.toString(), "$repoId",
+                gitlabApiProperties.accessToken
+            )
+        )
+
+        // TODO: right now we fire and forget, in a sense that we run the tool calculate the
+        // KPIs and forget the tool results. For this tool we want to manually store the results
+        // until it is included into the official CI/CD pipeline.
+
+        // delete cloned repo
+        try {
+            outDir.deleteRecursively()
+        } catch (e: Exception) {
+            logger.error("Delete directory after occmd run failed for dir $outDir")
+        }
+
+        return rawOccmdResults
+    }
+
+
+    private suspend fun runOccmd(execPath: String, flags: Array<String>): List<RawResultJson> = coroutineScope {
+        val toolResults = mutableListOf<RawResultJson>()
+        if (isExecutable(execPath)) {
+
+            val process = withContext(Dispatchers.IO) {
+                ProcessBuilder(execPath, *flags).start()
+            }
+            process.onExit().await()
+            val json = Json { ignoreUnknownKeys = true }
+            process.inputStream.bufferedReader().forEachLine {
+                toolResults.add(json.decodeFromString(it))
+            }
+        } else {
+            logger.error("Given execPath is not an executable $execPath.")
+        }
+
+        return@coroutineScope toolResults
+    }
+
+    private fun isExecutable(filePath: String): Boolean {
+        val path = Paths.get(filePath)
+        return isExecutable(path)
+    }
+
+    private suspend fun cloneGit(repoUrl: String, outDir: File) {
+        val git: Git = Git.cloneRepository()
+            .setURI(repoUrl)
+            .setDirectory(outDir)
+            .call()
+        git.close()
+    }
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/dto/VulnerabilityDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/dto/VulnerabilityDto.kt
new file mode 100644
index 00000000..c26385a1
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/dto/VulnerabilityDto.kt
@@ -0,0 +1,3 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.dto
+
+data class VulnerabilityDto(val cveIdentifier: String, val packageName: String, val severity: Double)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/DataJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/DataJson.kt
new file mode 100644
index 00000000..6f6ba58c
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/DataJson.kt
@@ -0,0 +1,17 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class DataJson(
+    @SerialName("description")
+    val description: String?,
+    @SerialName("id")
+    val id: String?,
+    @SerialName("references")
+    val references: List<ReferenceJson> = listOf(),
+    @SerialName("summary")
+    val summary: String?
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/OrtJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/OrtJson.kt
new file mode 100644
index 00000000..1173032f
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/OrtJson.kt
@@ -0,0 +1,13 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class OrtJson(
+    @SerialName("code")
+    val code: Int,
+    @SerialName("result")
+    val result: List<ResultJson> = mutableListOf()
+)
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ReferenceJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ReferenceJson.kt
similarity index 80%
rename from src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ReferenceJson.kt
rename to src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ReferenceJson.kt
index 19e5af82..58d3bd7f 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/taskManager/tasks/tools/ort/json/ReferenceJson.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ReferenceJson.kt
@@ -1,4 +1,4 @@
-package de.fraunhofer.iem.dataprovider.taskManager.tasks.tools.ort.json
+package de.fraunhofer.iem.dataprovider.tools.ort.json
 
 
 import kotlinx.serialization.SerialName
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ResultJson.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ResultJson.kt
new file mode 100644
index 00000000..de0edba9
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/json/ResultJson.kt
@@ -0,0 +1,27 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.json
+
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ResultJson(
+    @SerialName("createdAt")
+    val createdAt: String?,
+    @SerialName("cveId")
+    val cveId: String?,
+    @SerialName("data")
+    val data: DataJson?,
+    @SerialName("id")
+    val id: String?,
+    @SerialName("method")
+    val method: String?,
+    @SerialName("package")
+    val packageName: String?,
+    @SerialName("severity")
+    val severity: Double?,
+    @SerialName("updatedAt")
+    val updatedAt: String?,
+    @SerialName("version")
+    val version: String?
+)
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
new file mode 100644
index 00000000..1dfb2b77
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtService.kt
@@ -0,0 +1,91 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.service
+
+import de.fraunhofer.iem.dataprovider.configuration.OpenCodeApiProperties
+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.ort.dto.VulnerabilityDto
+import de.fraunhofer.iem.dataprovider.tools.ort.json.OrtJson
+import de.fraunhofer.iem.dataprovider.tools.ort.json.ResultJson
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.serialization.kotlinx.json.*
+import jakarta.annotation.PreDestroy
+import kotlinx.serialization.json.Json
+import org.springframework.stereotype.Service
+
+@Service
+class OrtService(private val openCodeApiProperties: OpenCodeApiProperties, private val toolService: ToolService) {
+
+    private val logger = getLogger(javaClass)
+
+    @PreDestroy
+    private fun destroy() {
+        logger.info("ORT service shutdown. Closing HTTP client.")
+        client.close()
+    }
+
+    private val client = getHttpClient()
+
+    private fun getHttpClient(): HttpClient {
+        return HttpClient(CIO) {
+            install(ContentNegotiation) {
+                json(
+                    Json { ignoreUnknownKeys = true }
+                )
+            }
+        }
+    }
+
+    val toolEntity: ToolEntity = getOrCreateToolEntity()
+
+
+    /**
+     * Queries the ORT API and transforms the received JSON objects into
+     * VulnerabilityDtos.
+     *
+     * When the API call fails, or contains malformed/incomplete
+     * elements this function returns an empty list.
+     */
+    suspend fun getOrtResults(repoId: Long): List<VulnerabilityDto> {
+
+        val ortResults = queryOrtApi(repoId)
+        logger.info("Got ${ortResults.size} ORT results for $repoId.")
+        return ortResults.mapNotNull {
+            if (it.cveId != null && it.packageName != null && it.severity != null) {
+                VulnerabilityDto(it.cveId, it.packageName, it.severity)
+            } else {
+                null
+            }
+        }
+    }
+
+    private final fun getOrCreateToolEntity(): ToolEntity {
+        val createToolDto = CreateToolDto("ORT")
+        return toolService.findOrCreateTool(createToolDto)
+    }
+
+    private suspend fun queryOrtApi(repoId: Long): List<ResultJson> {
+        return try {
+            logger.info("Query ORT API for repo with id $repoId")
+            val response: HttpResponse = client.get(getToolApiPath(repoId))
+            val ortJson = response.body<OrtJson>()
+            if (ortJson.code != 200) {
+                throw Exception("ORT API returned with code ${ortJson.code}")
+            }
+            ortJson.result
+        } catch (exception: Exception) {
+            logger.error("Query to ORT API failed with exception $exception")
+            emptyList()
+        }
+    }
+
+    private fun getToolApiPath(repoId: Long): String {
+        return "${openCodeApiProperties.basePath}$repoId${openCodeApiProperties.ort}"
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index b37ce441..1103212c 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,20 +1,24 @@
 spring.config.import=optional:classpath:.env[.properties]
-
 # Config for the OpencoDE platform
 # Token can be an empty string to access public repositories only
 opencode.host=https://gitlab.opencode.de/
-opencode.access-token=${OC_GL_APIKEY}
-
-# DB Login data
-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}
+opencode.access-token=${OC_GL_APIKEY:}
+# Tool APIs
+opencode.api.base-path=https://sl.dev.o4oe.de/api/v1/project/
+opencode.api.ort=/cve-result
 # API key to access this server's API
-security.api-key=${API_KEY}
-security.admin-password=${ADMIN_PASSWORD}
-directories.git-clone-target-directory=${GIT_CLONE_TARGET_DIRECTORY}
-directories.tool-results-target-directory=${TOOL_RESULTS_TARGET_DIRECTORY}
-
+#  The api key is needed for all routes.
+#  the admin password is needed for the repo changed route.
+#  It is expected as basic auth with the admin username
+# details can be found in configuration/security/WebSecurityConfiguration.kt
+security.api-key=${API_KEY:}
+security.admin-password=${ADMIN_PASSWORD:}
+security.admin-username=${ADMIN_USERNAME:}
+# OCCMD specific settings
+# path to the occmd tool executable
+# this can e.g, be the occmd.sh script in this project
+occmd.git-clone-target-directory=${GIT_CLONE_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
@@ -26,4 +30,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
diff --git a/src/main/resources/scripts/occmd.sh b/src/main/resources/scripts/occmd.sh
index 5e8f1241..bcd208ef 100755
--- a/src/main/resources/scripts/occmd.sh
+++ b/src/main/resources/scripts/occmd.sh
@@ -1,7 +1,9 @@
 #!/bin/sh
-EXEC=${1}
-PROJ_PATH=${2}
-PROJ_ID=${3}
+INSTALL_DIR=/occmd
+PROJ_PATH=${1}
+PROJ_ID=${2}
+API_KEY=${3}
 
-./"${EXEC}"/occmd check -d "${PROJ_PATH}" -i "${PROJ_ID}"
-#docker run -e OC_GL_APIKEY="${OC_GL_APIKEY}"-v /tmp/VulnerableSpringApp/:/opt/VulnerableSpringApp --rm occmd check -d /opt/VulnerableSpringApp -i 1108
\ No newline at end of file
+#export OC_GL_APIKEY="${API_KEY}" && .${INSTALL_DIR}/occmd check -d "${PROJ_PATH}" -i "${PROJ_ID}"
+(docker run -e OC_GL_APIKEY="${API_KEY}" -v "${PROJ_PATH}":/opt/PROJ --rm occmd check -d /opt/PROJ -i "${PROJ_ID}")
+exit 0
\ No newline at end of file
diff --git a/src/main/resources/scripts/ort/config.yml b/src/main/resources/scripts/ort/config.yml
deleted file mode 100644
index 824c3f61..00000000
--- a/src/main/resources/scripts/ort/config.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-ort:
-  advisor:
-    osv:
-      serverUrl: "https://api-staging.osv.dev"
-    forceOverwrite: true
\ No newline at end of file
diff --git a/src/main/resources/scripts/ort/ort_advisor.sh b/src/main/resources/scripts/ort/ort_advisor.sh
deleted file mode 100755
index db8103bb..00000000
--- a/src/main/resources/scripts/ort/ort_advisor.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-PROJECT_DIRECTORY=${1}
-OUTPUT_DIRECTORY=${2}
-echo Advisor Started
-echo Input directory: "${PROJECT_DIRECTORY}" Output directory: "${OUTPUT_DIRECTORY}"
-
-script_dir="$(dirname "$0")"
-
- #add --network vulnerablecode_mynetwork when running together with a custom vulnerable code instance
-docker run --rm \
--v "${script_dir}":/config \
--v "${PROJECT_DIRECTORY}":/project \
--v "${OUTPUT_DIRECTORY}":/result \
-ort --config /config/config.yml --info advise -f JSON -i /project/analyzer-result.json --output-dir /result -a OSV
-exit 0
\ No newline at end of file
diff --git a/src/main/resources/scripts/ort/ort_analyzer.sh b/src/main/resources/scripts/ort/ort_analyzer.sh
deleted file mode 100755
index c2a5d860..00000000
--- a/src/main/resources/scripts/ort/ort_analyzer.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-PROJECT_DIRECTORY=${1}
-OUTPUT_DIRECTORY=${2}
-echo Analyzer started
-echo Input directory: "${PROJECT_DIRECTORY}" Output directory: "${OUTPUT_DIRECTORY}"
-
-script_dir="$(dirname "$0")"
-
-docker run --rm \
--v "${script_dir}":/config \
--v "${PROJECT_DIRECTORY}":/project \
--v "${OUTPUT_DIRECTORY}":/result \
-ort --info --config /config/config.yml analyze -i /project --output-dir /result -f JSON
-
-exit 0
\ No newline at end of file
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/DependencyDatabaseTest.kt b/src/test/kotlin/de/fraunhofer/iem/dataprovider/DependencyDatabaseTest.kt
deleted file mode 100644
index dbd725ca..00000000
--- a/src/test/kotlin/de/fraunhofer/iem/dataprovider/DependencyDatabaseTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package de.fraunhofer.iem.dataprovider
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityScoreCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.enumeration.VulnerabilityScoringSystemEnum
-import de.fraunhofer.iem.dataprovider.dependency.repository.DependencyRepository
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.fail
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
-
-@DataJpaTest
-class DependencyDatabaseTest @Autowired constructor(
-    val dependencyRepository: DependencyRepository
-) {
-
-    @OptIn(ExperimentalCoroutinesApi::class)
-    @Test
-    fun saveDependencyEntityToDb() = runTest {
-
-        val vulnerabilityScores1 = mutableListOf<VulnerabilityScoreCreateDto>()
-        vulnerabilityScores1.add(VulnerabilityScoreCreateDto("1.0", VulnerabilityScoringSystemEnum.CVSSV3))
-        vulnerabilityScores1.add(VulnerabilityScoreCreateDto("2.0", VulnerabilityScoringSystemEnum.CVSSV3))
-
-        val vulnerabilityScores2 = mutableListOf<VulnerabilityScoreCreateDto>()
-        vulnerabilityScores2.add(VulnerabilityScoreCreateDto("3.0", VulnerabilityScoringSystemEnum.CVSSV3))
-        vulnerabilityScores2.add(VulnerabilityScoreCreateDto("4.0", VulnerabilityScoringSystemEnum.CVSSV3))
-
-
-        val vulnerabilities = mutableListOf<VulnerabilityCreateDto>()
-        vulnerabilities.add(VulnerabilityCreateDto("MyCVETestIdent1", vulnerabilityScores1))
-        vulnerabilities.add(VulnerabilityCreateDto("MyCVETestIdent2", vulnerabilityScores2))
-
-        val createDependencyDependencyCreateDto = DependencyCreateDto(name = "TestDependency", vulnerabilities)
-
-        val dbObject = createDependencyDependencyCreateDto.toDbObject()
-        assert(dbObject.name == "TestDependency")
-        assert(dbObject.vulnerabilities.size == 2)
-        assert(dbObject.vulnerabilities.first().cveIdentifier == "MyCVETestIdent1")
-        val savedInstance = dependencyRepository.save(dbObject)
-        val queriedInstance =
-            dependencyRepository.findById(savedInstance.id!!).orElseGet { fail("Instance was not found in db") }
-        assertThat(savedInstance).isEqualTo(queriedInstance)
-    }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/WorkerTest.kt b/src/test/kotlin/de/fraunhofer/iem/dataprovider/WorkerTest.kt
deleted file mode 100644
index 20f63e38..00000000
--- a/src/test/kotlin/de/fraunhofer/iem/dataprovider/WorkerTest.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package de.fraunhofer.iem.dataprovider
-
-import de.fraunhofer.iem.dataprovider.taskManager.Worker
-import de.fraunhofer.iem.dataprovider.taskManager.events.Event
-import de.fraunhofer.iem.dataprovider.taskManager.events.TaskFailedEvent
-import de.fraunhofer.iem.dataprovider.taskManager.tasks.Task
-import io.mockk.mockk
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.jupiter.api.Test
-import java.util.concurrent.atomic.AtomicInteger
-
-class WorkerTest {
-
-
-    private class ExceptionTask(override val responseChannel: suspend (event: Event) -> Unit) : Task() {
-        override suspend fun execute() {
-            throw Exception("Execution crashed!")
-        }
-    }
-
-    private class WaitingTask(override val responseChannel: suspend (event: Event) -> Unit) : Task() {
-        override suspend fun execute() {
-            val testEvent = mockk<Event>()
-            responseChannel(testEvent)
-        }
-    }
-
-    @OptIn(ExperimentalCoroutinesApi::class)
-    @Test
-    fun workerExceptionTest() = runTest {
-        val worker = Worker("Worker", this)
-
-        val successfulTasks = AtomicInteger()
-        val exceptions = AtomicInteger()
-
-        suspend fun responseChannelDummy(event: Event): Unit {
-            when (event) {
-                is TaskFailedEvent -> exceptions.incrementAndGet()
-                else -> successfulTasks.incrementAndGet()
-            }
-            if (exceptions.get() == 1 && successfulTasks.get() == 2) {
-                worker.close()
-            }
-        }
-
-        worker.addTask(WaitingTask(::responseChannelDummy))
-        worker.addTask(ExceptionTask(::responseChannelDummy))
-        worker.addTask(WaitingTask(::responseChannelDummy))
-    }
-}
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/OrtAdvisorTaskTest.kt b/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/OrtAdvisorTaskTest.kt
deleted file mode 100644
index 385ab250..00000000
--- a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/OrtAdvisorTaskTest.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package de.fraunhofer.iem.dataprovider.ort
-
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.jupiter.api.Test
-
-
-class OrtAdvisorTaskTest {
-
-    @OptIn(ExperimentalCoroutinesApi::class)
-    @Test
-    fun testOrtTask() = runTest(dispatchTimeoutMs = 500_000L) {
-//        val worker = Worker("Worker", this)
-//        val repositoryDirectoryPath = Paths.get("").toAbsolutePath().toString()
-//        val outputDirectoryPath = Paths.get("src/test/testResults").toAbsolutePath().toString()
-//
-//
-//        suspend fun responseChannelDummy(event: Event): Unit {
-//            println("Received event $event")
-//            worker.close()
-//        }
-//
-//        val repoId = UUID.randomUUID()
-//        val groupId = UUID.randomUUID()
-//        val dependencyService = mockk<DependencyService>()
-//        val toolService = mockk<ToolService>()
-//        every { dependencyService.save(any()) } returns Unit
-//
-//        val ortTask = OrtTask(
-//            repositoryDirectoryPath,
-//            outputDirectoryPath,
-//            ::responseChannelDummy,
-//            repoId,
-//            groupId,
-//            dependencyService,
-////            toolService
-//        )
-//        worker.addTask(ortTask)
-    }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ParseOrtAdvisorResult.kt b/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ParseOrtAdvisorResult.kt
deleted file mode 100644
index 61371ed5..00000000
--- a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ParseOrtAdvisorResult.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package de.fraunhofer.iem.dataprovider.ort
-
-import de.fraunhofer.iem.dataprovider.dependency.dto.DependencyCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.dto.VulnerabilityScoreCreateDto
-import de.fraunhofer.iem.dataprovider.dependency.enumeration.VulnerabilityScoringSystemEnum
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.jupiter.api.Test
-
-
-class ParseOrtAdvisorResult {
-
-    @Test
-    fun parseOrt() {
-//        val res =
-//            getOrtResultsFromFile(Paths.get("src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json"))
-//        val advisorResult = res.advisorResults
-//        assert(advisorResult[0].identifier == "first" && advisorResult[1].identifier == "second")
-//        assert(advisorResult[0].vulnerabilities[0].id == "CVE-2021-45105")
-//        assert(advisorResult[0].vulnerabilities[0].references[0].severity == "6.6")
-//
-//        val packages = res.packages
-//        assert(packages[0].nameAndVersion == "Maven:ch.qos.logback:logback-classic:1.4.7")
-    }
-
-    @OptIn(ExperimentalCoroutinesApi::class)
-    @Test
-    fun parseOrtTask() = runTest {
-//
-//        suspend fun responseChannelDummy(event: Event): Unit {
-//        }
-//
-//        val depService = mockk<DependencyService>()
-//        val toolService = mockk<ToolService>()
-//
-//        val path = Paths.get("src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json")
-//        val ortAdvisorTask = OrtAdvisorTask(
-//            repositoryDirectoryPath = "",
-//            outputDirectoryPath = "",
-//            responseChannel = ::responseChannelDummy,
-//            repoId = UUID.randomUUID(),
-//            dependencyService = depService,
-////            toolService = toolService
-//        )
-//        val res = ortAdvisorTask.parseProcessResults(path.toAbsolutePath())
-//        assert(res.size == 4)
-//        assert(res[0].name == "Maven:ch.qos.logback:logback-classic:1.4.7")
-//        assert(res[1].name == "Maven:ch.qos.logback:logback-core:1.4.7")
-//        assert(res[2].name == "first" && res[2].vulnerabilities.size == 2)
-//        assert(res[2].vulnerabilities[0].cveIdentifier == "CVE-2021-45105" && res[2].vulnerabilities[0].vulnerabilityScores[0].severity == "6.6")
-//        assert(res[2].vulnerabilities[0].vulnerabilityScores[1].severity == "MEDIUM" && res[2].vulnerabilities[0].vulnerabilityScores[1].scoringSystem == VulnerabilityScoringSystemEnum.CVSSV3_1)
-//        assert(res[2].vulnerabilities[0].vulnerabilityScores[0].scoringSystem == VulnerabilityScoringSystemEnum.CVSSV3)
-    }
-
-    @OptIn(ExperimentalCoroutinesApi::class)
-    @Test
-    fun ortToDbObject() = runTest {
-
-        val vulnerabilityScores1 = mutableListOf<VulnerabilityScoreCreateDto>()
-        vulnerabilityScores1.add(VulnerabilityScoreCreateDto("1.0", VulnerabilityScoringSystemEnum.CVSSV3))
-        vulnerabilityScores1.add(VulnerabilityScoreCreateDto("2.0", VulnerabilityScoringSystemEnum.CVSSV3))
-
-        val vulnerabilityScores2 = mutableListOf<VulnerabilityScoreCreateDto>()
-        vulnerabilityScores2.add(VulnerabilityScoreCreateDto("3.0", VulnerabilityScoringSystemEnum.CVSSV3))
-        vulnerabilityScores2.add(VulnerabilityScoreCreateDto("4.0", VulnerabilityScoringSystemEnum.CVSSV3))
-
-
-        val vulnerabilities = mutableListOf<VulnerabilityCreateDto>()
-        vulnerabilities.add(VulnerabilityCreateDto("MyCVETestIdent1", vulnerabilityScores1))
-        vulnerabilities.add(VulnerabilityCreateDto("MyCVETestIdent2", vulnerabilityScores2))
-
-        val createDependencyDependencyCreateDto = DependencyCreateDto(name = "TestDependency", vulnerabilities)
-
-        val dbObject = createDependencyDependencyCreateDto.toDbObject()
-        assert(dbObject.name == "TestDependency")
-        assert(dbObject.vulnerabilities.size == 2)
-        assert(dbObject.vulnerabilities.first().cveIdentifier == "MyCVETestIdent1")
-    }
-}
\ No newline at end of file
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json b/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json
deleted file mode 100644
index ecf6a1c9..00000000
--- a/src/test/kotlin/de/fraunhofer/iem/dataprovider/ort/ort-advisor-example-results.json
+++ /dev/null
@@ -1,158 +0,0 @@
-{
-  "analyzer": {
-    "result": {
-      "packages": [
-        {
-          "id": "Maven:ch.qos.logback:logback-classic:1.4.7",
-          "purl": "pkg:maven/ch.qos.logback/logback-classic@1.4.7"
-        },
-        {
-          "id": "Maven:ch.qos.logback:logback-core:1.4.7",
-          "purl": "pkg:maven/ch.qos.logback/logback-core@1.4.7"
-        },
-        {
-          "id": "first",
-          "purl": "pkg:first"
-        }
-      ]
-    }
-  },
-  "advisor": {
-    "results": {
-      "advisor_results": {
-        "first": [
-          {
-            "advisor": {
-              "name": "VulnerableCode",
-              "capabilities": [
-                "VULNERABILITIES"
-              ]
-            },
-            "summary": {
-              "start_time": "2023-06-05T08:54:18.739380591Z",
-              "end_time": "2023-06-05T08:54:21.192752259Z",
-              "issues": [
-                {
-                  "timestamp": "2023-06-05T08:54:21.196167384Z",
-                  "source": "VulnerableCode",
-                  "message": "Failed to map VulnerabilityReference(url=https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:4.10\\(0.15\\):*:*:*:*:*:*:*, scores=[]) to ORT model due to java.net.URISyntaxException: Illegal character in query at index 122: https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:4.10\\(0.15\\):*:*:*:*:*:*:*.",
-                  "severity": "HINT"
-                },
-                {
-                  "timestamp": "2023-06-05T08:54:21.200655759Z",
-                  "source": "VulnerableCode",
-                  "message": "Failed to map VulnerabilityReference(url=https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:5.3\\(0\\):*:*:*:*:*:*:*, scores=[]) to ORT model due to java.net.URISyntaxException: Illegal character in query at index 121: https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:5.3\\(0\\):*:*:*:*:*:*:*.",
-                  "severity": "HINT"
-                }
-              ]
-            },
-            "defects": [],
-            "vulnerabilities": [
-              {
-                "id": "CVE-2021-45105",
-                "references": [
-                  {
-                    "url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-44832.json",
-                    "scoring_system": "cvssv3",
-                    "severity": "6.6"
-                  },
-                  {
-                    "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-784507.pdf",
-                    "scoring_system": null,
-                    "severity": null
-                  },
-                  {
-                    "url": "https://github.com/advisories/GHSA-8489-44mv-ggj8",
-                    "scoring_system": "cvssv3.1_qr",
-                    "severity": "MEDIUM"
-                  }
-                ]
-              },
-              {
-                "id": "CVE-2021-44832",
-                "references": [
-                  {
-                    "url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-44832.json",
-                    "scoring_system": "cvssv3",
-                    "severity": "6.6"
-                  },
-                  {
-                    "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-784507.pdf",
-                    "scoring_system": null,
-                    "severity": null
-                  },
-                  {
-                    "url": "https://github.com/advisories/GHSA-8489-44mv-ggj8",
-                    "scoring_system": "cvssv3.1_qr",
-                    "severity": "CRITICAL"
-                  }
-                ]
-              }
-            ]
-          }
-        ],
-        "second": [
-          {
-            "advisor": {
-              "name": "VulnerableCode",
-              "capabilities": [
-                "VULNERABILITIES"
-              ]
-            },
-            "summary": {
-              "start_time": "2023-06-05T08:54:18.739380591Z",
-              "end_time": "2023-06-05T08:54:21.192752259Z",
-              "issues": [
-                {
-                  "timestamp": "2023-06-05T08:54:21.196167384Z",
-                  "source": "VulnerableCode",
-                  "message": "Failed to map VulnerabilityReference(url=https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:4.10\\(0.15\\):*:*:*:*:*:*:*, scores=[]) to ORT model due to java.net.URISyntaxException: Illegal character in query at index 122: https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:4.10\\(0.15\\):*:*:*:*:*:*:*.",
-                  "severity": "HINT"
-                },
-                {
-                  "timestamp": "2023-06-05T08:54:21.200655759Z",
-                  "source": "VulnerableCode",
-                  "message": "Failed to map VulnerabilityReference(url=https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:5.3\\(0\\):*:*:*:*:*:*:*, scores=[]) to ORT model due to java.net.URISyntaxException: Illegal character in query at index 121: https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:2.3:a:cisco:cloudcenter_suite:5.3\\(0\\):*:*:*:*:*:*:*.",
-                  "severity": "HINT"
-                }
-              ]
-            },
-            "defects": [],
-            "vulnerabilities": [
-              {
-                "id": "CVE-2021-45105",
-                "references": [
-                  {
-                    "url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-44832.json",
-                    "scoring_system": "cvssv3",
-                    "severity": "6.6"
-                  },
-                  {
-                    "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-784507.pdf",
-                    "scoring_system": null,
-                    "severity": null
-                  }
-                ]
-              },
-              {
-                "id": "CVE-2021-44832",
-                "references": [
-                  {
-                    "url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-44832.json",
-                    "scoring_system": "cvssv3",
-                    "severity": "8.6"
-                  },
-                  {
-                    "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-784507.pdf",
-                    "scoring_system": null,
-                    "severity": null
-                  }
-                ]
-              }
-            ]
-          }
-        ]
-      }
-    }
-  }
-}
diff --git a/src/test/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtServiceTest.kt b/src/test/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtServiceTest.kt
new file mode 100644
index 00000000..cce3b444
--- /dev/null
+++ b/src/test/kotlin/de/fraunhofer/iem/dataprovider/tools/ort/service/OrtServiceTest.kt
@@ -0,0 +1,123 @@
+package de.fraunhofer.iem.dataprovider.tools.ort.service
+
+import de.fraunhofer.iem.dataprovider.configuration.OpenCodeApiProperties
+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.json.DataJson
+import de.fraunhofer.iem.dataprovider.tools.ort.json.ResultJson
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.spyk
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.jupiter.api.Test
+
+class OrtServiceTest {
+
+    private fun createOrtService(): OrtService {
+        val openCodeApiProperties = OpenCodeApiProperties("/localhost", "/ort")
+        val toolService = mockk<ToolService>()
+        every { toolService.findOrCreateTool(CreateToolDto("ORT")) } returns ToolEntity(name = "ORT")
+        return OrtService(openCodeApiProperties, toolService)
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun getOrtResultsEmpty() = runTest {
+        val ortService = spyk(createOrtService(), recordPrivateCalls = true)
+        every { ortService invoke "queryOrtApi" withArguments listOf(100.toLong()) } returns emptyList<ResultJson>()
+        val ortResults = ortService.getOrtResults(100)
+        assert(ortResults.isEmpty())
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun getOrtResults() = runTest {
+        val ortService = spyk(createOrtService(), recordPrivateCalls = true)
+        val resultJson = listOf(
+            ResultJson(
+                createdAt = "",
+                cveId = "",
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = "",
+                severity = null,
+                updatedAt = "",
+                version = ""
+            ),
+            ResultJson(
+                createdAt = "",
+                cveId = "",
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = null,
+                severity = 0.0,
+                updatedAt = "",
+                version = ""
+            ),
+            ResultJson(
+                createdAt = "",
+                cveId = null,
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = "",
+                severity = 0.0,
+                updatedAt = "",
+                version = ""
+            ),
+            ResultJson(
+                createdAt = null,
+                cveId = "7",
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = "",
+                severity = 0.0,
+                updatedAt = "",
+                version = ""
+            ),
+            ResultJson(
+                createdAt = "",
+                cveId = "11",
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = "Test",
+                severity = 0.0,
+                updatedAt = "",
+                version = ""
+            ),
+            ResultJson(
+                createdAt = "",
+                cveId = "42",
+                data = DataJson(id = "", description = "", references = emptyList(), summary = ""),
+                id = "",
+                method = "",
+                packageName = "",
+                severity = 0.0,
+                updatedAt = "",
+                version = ""
+            ),
+        )
+        every { ortService invoke "queryOrtApi" withArguments listOf(100.toLong()) } returns resultJson
+        val ortResults = ortService.getOrtResults(100)
+        assert(ortResults.size == 3)
+        assert(ortResults[0].severity == 0.0)
+        assert(ortResults[1].packageName == "Test")
+        assert(ortResults[0].cveIdentifier == "7")
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun getOrtResultsFailingApiRequest() = runTest {
+        val ortService = createOrtService()
+
+        val ortResults = ortService.getOrtResults(100)
+        assert(ortResults.isEmpty())
+    }
+
+}
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
index eeaa2044..bd6e3acb 100644
--- a/src/test/resources/application.properties
+++ b/src/test/resources/application.properties
@@ -1,4 +1,11 @@
 spring.datasource.driver-class-name=org.h2.Driver
 spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
 spring.datasource.username=sa
-spring.datasource.password=sa
\ No newline at end of file
+spring.datasource.password=sa
+opencode.host=https://gitlab.opencode.de/
+opencode.access-token=notARealKey
+# API key to access this server's API
+security.api-key=notARealKeyWithAtLeastThirtyCharactersDueToValidation
+security.admin-password=notARealKeyWithAtLeastThirtyCharactersDueToValidation
+directories.git-clone-target-directory=/tmp/test
+directories.tool-results-target-directory=/tmp/test
\ No newline at end of file
diff --git a/tools/db/api.json b/tools/db/api.json
index 1050249c..a073eb27 100644
--- a/tools/db/api.json
+++ b/tools/db/api.json
@@ -1,4148 +1,198 @@
 {
-  "ort": {
-    "repository": {
-      "vcs": {
-        "type": "Git",
-        "url": "git@gitlab.opencode.de:opencode-analyzer/VulnerableSpringApp.git",
-        "revision": "b83a318f9248ba650621047242b4b5faa9e73ba0",
-        "path": ""
-      },
-      "vcs_processed": {
-        "type": "Git",
-        "url": "ssh://git@gitlab.opencode.de/opencode-analyzer/VulnerableSpringApp.git",
-        "revision": "b83a318f9248ba650621047242b4b5faa9e73ba0",
-        "path": ""
-      },
-      "config": {}
-    },
-    "analyzer": {
-      "start_time": "2023-08-03T11:30:29.942025001Z",
-      "end_time": "2023-08-03T11:30:50.652305928Z",
-      "environment": {
-        "ort_version": "DOCKER-SNAPSHOT",
-        "java_version": "17.0.8",
-        "os": "Linux",
-        "processors": 4,
-        "max_memory": 1031798784,
-        "variables": {
-          "JAVA_HOME": "/opt/java/openjdk",
-          "ANDROID_HOME": "/opt/android-sdk"
-        },
-        "tool_versions": {}
-      },
-      "config": {
-        "allow_dynamic_versions": false,
-        "skip_excluded": false
-      },
-      "result": {
-        "projects": [
-          {
-            "id": "Maven:com.example:demo:0.0.1-SNAPSHOT",
-            "definition_file_path": "pom.xml",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "vcs": {
-              "type": "",
-              "url": "",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@gitlab.opencode.de/opencode-analyzer/VulnerableSpringApp.git",
-              "revision": "b83a318f9248ba650621047242b4b5faa9e73ba0",
-              "path": ""
-            },
-            "homepage_url": "https://spring.io/projects/spring-boot/demo",
-            "scope_names": [
-              "compile",
-              "test"
-            ]
-          }
-        ],
-        "packages": [
-          {
-            "id": "Maven:ch.qos.logback:logback-classic:1.4.7",
-            "purl": "pkg:maven/ch.qos.logback/logback-classic@1.4.7",
-            "authors": [
-              "Ceki Gulcu",
-              "Joern Huxhorn",
-              "QOS.ch"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License - v 1.0",
-              "GNU Lesser General Public License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-1.0 OR LGPL-2.1-or-later",
-              "mapped": {
-                "Eclipse Public License - v 1.0": "EPL-1.0",
-                "GNU Lesser General Public License": "LGPL-2.1-or-later"
-              }
-            },
-            "description": "logback-classic module",
-            "homepage_url": "http://logback.qos.ch/logback-classic",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.4.7/logback-classic-1.4.7.jar",
-              "hash": {
-                "value": "307944865579a6d490e6a4cbb5082dc8f36536ca",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/ch/qos/logback/logback-classic/1.4.7/logback-classic-1.4.7-sources.jar",
-              "hash": {
-                "value": "f04b2c50eee3f328f2b457f7005ebc1727e501f4",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/logback.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/logback.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:ch.qos.logback:logback-core:1.4.7",
-            "purl": "pkg:maven/ch.qos.logback/logback-core@1.4.7",
-            "authors": [
-              "Ceki Gulcu",
-              "Joern Huxhorn",
-              "QOS.ch"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License - v 1.0",
-              "GNU Lesser General Public License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-1.0 OR LGPL-2.1-or-later",
-              "mapped": {
-                "Eclipse Public License - v 1.0": "EPL-1.0",
-                "GNU Lesser General Public License": "LGPL-2.1-or-later"
-              }
-            },
-            "description": "logback-core module",
-            "homepage_url": "http://logback.qos.ch/logback-core",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.4.7/logback-core-1.4.7.jar",
-              "hash": {
-                "value": "a2948dae4013d0e9486141b4d638d8951becb767",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/ch/qos/logback/logback-core/1.4.7/logback-core-1.4.7-sources.jar",
-              "hash": {
-                "value": "f3486d702b79a0249e8f26adfb44866e3741cc3a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/logback.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/logback.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:com.jayway.jsonpath:json-path:2.8.0",
-            "purl": "pkg:maven/com.jayway.jsonpath/json-path@2.8.0",
-            "authors": [
-              "Kalle Stenflo"
-            ],
-            "declared_licenses": [
-              "The Apache Software License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache Software License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "A library to query and verify JSON",
-            "homepage_url": "https://github.com/jayway/JsonPath",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.8.0/json-path-2.8.0.jar",
-              "hash": {
-                "value": "b4ab3b7a9e425655a0ca65487bbbd6d7ddb75160",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/com/jayway/jsonpath/json-path/2.8.0/json-path-2.8.0-sources.jar",
-              "hash": {
-                "value": "4cef8f7eaa1e056e5eae9bd000e43b342fdffda8",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/jayway/JsonPath.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/jayway/JsonPath.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:com.vaadin.external.google:android-json:0.0.20131108.vaadin1",
-            "purl": "pkg:maven/com.vaadin.external.google/android-json@0.0.20131108.vaadin1",
-            "authors": [
-              "Google"
-            ],
-            "declared_licenses": [
-              "Apache License 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License 2.0": "Apache-2.0"
-              }
-            },
-            "description": "  JSON (JavaScript Object Notation) is a lightweight data-interchange format.\n      This is the org.json compatible Android implementation extracted from the Android SDK\n    ",
-            "homepage_url": "http://developer.android.com/sdk",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1.jar",
-              "hash": {
-                "value": "fa26d351fe62a6a17f5cda1287c1c6110dec413f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/com/vaadin/external/google/android-json/0.0.20131108.vaadin1/android-json-0.0.20131108.vaadin1-sources.jar",
-              "hash": {
-                "value": "bf42d7e47a3228513b626dd7d37ac6f072aeca4f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "http",
-              "url": "http://developer.android.com/sdk/",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "http",
-              "url": "http://developer.android.com/sdk",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:jakarta.activation:jakarta.activation-api:2.1.2",
-            "purl": "pkg:maven/jakarta.activation/jakarta.activation-api@2.1.2",
-            "authors": [
-              "Eclipse Foundation",
-              "Oracle"
-            ],
-            "declared_licenses": [
-              "EDL 1.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "BSD-3-Clause",
-              "mapped": {
-                "EDL 1.0": "BSD-3-Clause"
-              }
-            },
-            "description": "Jakarta Activation API 2.1 Specification",
-            "homepage_url": "https://github.com/jakartaee/jaf-api",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.2/jakarta.activation-api-2.1.2.jar",
-              "hash": {
-                "value": "640c0d5aff45dbff1e1a1bc09673ff3a02b1ba12",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/activation/jakarta.activation-api/2.1.2/jakarta.activation-api-2.1.2-sources.jar",
-              "hash": {
-                "value": "d0310cf32e4c43f65b942c18cb2cc2bccfe2de37",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "ssh://git@github.com/jakartaee/jaf-api.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/jakartaee/jaf-api.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:jakarta.annotation:jakarta.annotation-api:2.1.1",
-            "purl": "pkg:maven/jakarta.annotation/jakarta.annotation-api@2.1.1",
-            "authors": [
-              "Eclipse Foundation",
-              "Oracle Corp."
-            ],
-            "declared_licenses": [
-              "EPL 2.0",
-              "GPL2 w/ CPE"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0",
-              "mapped": {
-                "EPL 2.0": "EPL-2.0",
-                "GPL2 w/ CPE": "GPL-2.0-only WITH Classpath-exception-2.0"
-              }
-            },
-            "description": "Jakarta Annotations API",
-            "homepage_url": "https://projects.eclipse.org/projects/ee4j.ca",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar",
-              "hash": {
-                "value": "48b9bda22b091b1f48b13af03fe36db3be6e1ae3",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1-sources.jar",
-              "hash": {
-                "value": "3beea3ed2e687d9bd8a78c00e18951fffccefe90",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/eclipse-ee4j/common-annotations-api.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/eclipse-ee4j/common-annotations-api.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:jakarta.xml.bind:jakarta.xml.bind-api:4.0.0",
-            "purl": "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@4.0.0",
-            "authors": [
-              "Eclipse Foundation",
-              "Oracle Corporation"
-            ],
-            "declared_licenses": [
-              "Eclipse Distribution License - v 1.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "BSD-3-Clause",
-              "mapped": {
-                "Eclipse Distribution License - v 1.0": "BSD-3-Clause"
-              }
-            },
-            "description": "Jakarta XML Binding API",
-            "homepage_url": "https://github.com/eclipse-ee4j/jaxb-api/jakarta.xml.bind-api",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.0/jakarta.xml.bind-api-4.0.0.jar",
-              "hash": {
-                "value": "bbb399208d288b15ec101fa4fcfc4bd77cedc97a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/jakarta/xml/bind/jakarta.xml.bind-api/4.0.0/jakarta.xml.bind-api-4.0.0-sources.jar",
-              "hash": {
-                "value": "b8e46353907cfaccef843fff62d72476f8ad88ce",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/eclipse-ee4j/jaxb-api.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/eclipse-ee4j/jaxb-api.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:net.bytebuddy:byte-buddy:1.14.4",
-            "purl": "pkg:maven/net.bytebuddy/byte-buddy@1.14.4",
-            "authors": [
-              "Rafael Winterhalter"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Byte Buddy is a Java library for creating Java classes at run time.\n        This artifact is a build of Byte Buddy with all ASM dependencies repackaged into its own name space.",
-            "homepage_url": "https://bytebuddy.net/byte-buddy",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.14.4/byte-buddy-1.14.4.jar",
-              "hash": {
-                "value": "20498aaec9b00a5cfdb831e7bf68feafa833ce4b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy/1.14.4/byte-buddy-1.14.4-sources.jar",
-              "hash": {
-                "value": "94651fa92930ce2d26e3d5e4a7af5631f2f6cb2c",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git@github.com:raphw/byte-buddy.git",
-              "revision": "byte-buddy-1.14.4",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/raphw/byte-buddy.git",
-              "revision": "byte-buddy-1.14.4",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:net.bytebuddy:byte-buddy-agent:1.14.4",
-            "purl": "pkg:maven/net.bytebuddy/byte-buddy-agent@1.14.4",
-            "authors": [
-              "Rafael Winterhalter"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "The Byte Buddy agent offers convenience for attaching an agent to the local or a remote VM.",
-            "homepage_url": "https://bytebuddy.net/byte-buddy-agent",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.14.4/byte-buddy-agent-1.14.4.jar",
-              "hash": {
-                "value": "3bf5ac1104554908cc623e40e58a00be37c35f36",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/bytebuddy/byte-buddy-agent/1.14.4/byte-buddy-agent-1.14.4-sources.jar",
-              "hash": {
-                "value": "996d4bbc74a0bfc5180b442d7be19ce26a1e38fe",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git@github.com:raphw/byte-buddy.git",
-              "revision": "byte-buddy-1.14.4",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/raphw/byte-buddy.git",
-              "revision": "byte-buddy-1.14.4",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:net.minidev:accessors-smart:2.4.9",
-            "purl": "pkg:maven/net.minidev/accessors-smart@2.4.9",
-            "authors": [
-              "Chemouni Uriel",
-              "Uriel Chemouni",
-              "ZhangJian He"
-            ],
-            "declared_licenses": [
-              "The Apache Software License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache Software License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Java reflect give poor performance on getter setter an constructor calls, accessors-smart use ASM to speed up those calls.",
-            "homepage_url": "https://urielch.github.io/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.4.9/accessors-smart-2.4.9.jar",
-              "hash": {
-                "value": "32e540749224c22c9b17de8137e916aae9057e22",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/minidev/accessors-smart/2.4.9/accessors-smart-2.4.9-sources.jar",
-              "hash": {
-                "value": "d287b022105b7b85df83e254e398e6e5d415ee44",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/netplex/json-smart-v2.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/netplex/json-smart-v2.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:net.minidev:json-smart:2.4.10",
-            "purl": "pkg:maven/net.minidev/json-smart@2.4.10",
-            "authors": [
-              "Chemouni Uriel",
-              "Eitan Raviv",
-              "Uriel Chemouni",
-              "ZhangJian He"
-            ],
-            "declared_licenses": [
-              "The Apache Software License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache Software License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.",
-            "homepage_url": "https://urielch.github.io/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.4.10/json-smart-2.4.10.jar",
-              "hash": {
-                "value": "91cb329e9424bf32131eeb1ce2d17bf31b9899bc",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/net/minidev/json-smart/2.4.10/json-smart-2.4.10-sources.jar",
-              "hash": {
-                "value": "d0a77c330fc6ea765d002d598ff1e2328b5aeda7",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/netplex/json-smart-v2.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/netplex/json-smart-v2.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.apache.logging.log4j:log4j-api:2.14.1",
-            "purl": "pkg:maven/org.apache.logging.log4j/log4j-api@2.14.1",
-            "authors": [
-              "Bruce Brouwer",
-              "Carter Kozak",
-              "CloudBees",
-              "Nextiva",
-              "Nick Williams",
-              "Remko Popma",
-              "Rocket Software",
-              "Scott Deboy",
-              "Spotify",
-              "The Apache Software Foundation"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "The Apache Log4j API",
-            "homepage_url": "https://logging.apache.org/log4j/2.x/log4j-api/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-api/2.14.1/log4j-api-2.14.1.jar",
-              "hash": {
-                "value": "cd8858fbbde69f46bce8db1152c18a43328aae78",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-api/2.14.1/log4j-api-2.14.1-sources.jar",
-              "hash": {
-                "value": "b2327c47ca413c1ec183575b19598e281fcd74d8",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://gitbox.apache.org/repos/asf/logging-log4j2.git",
-              "revision": "log4j-2.14.1-rc1",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://gitbox.apache.org/repos/asf/logging-log4j2.git",
-              "revision": "log4j-2.14.1-rc1",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.apache.logging.log4j:log4j-core:2.14.1",
-            "purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1",
-            "authors": [
-              "Bruce Brouwer",
-              "Carter Kozak",
-              "CloudBees",
-              "Nextiva",
-              "Nick Williams",
-              "Remko Popma",
-              "Rocket Software",
-              "Scott Deboy",
-              "Spotify",
-              "The Apache Software Foundation"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "The Apache Log4j Implementation",
-            "homepage_url": "https://logging.apache.org/log4j/2.x/log4j-core/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.14.1/log4j-core-2.14.1.jar",
-              "hash": {
-                "value": "9141212b8507ab50a45525b545b39d224614528b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-core/2.14.1/log4j-core-2.14.1-sources.jar",
-              "hash": {
-                "value": "7f640e4855733d9532eed15af62c54956e7b8224",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://gitbox.apache.org/repos/asf/logging-log4j2.git",
-              "revision": "log4j-2.14.1-rc1",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://gitbox.apache.org/repos/asf/logging-log4j2.git",
-              "revision": "log4j-2.14.1-rc1",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.apache.logging.log4j:log4j-to-slf4j:2.20.0",
-            "purl": "pkg:maven/org.apache.logging.log4j/log4j-to-slf4j@2.20.0",
-            "authors": [
-              "Apple",
-              "Bruce Brouwer",
-              "Carter Kozak",
-              "Christian Grobmeier",
-              "Nextiva",
-              "Nick Williams",
-              "Piotr P. Karwasz",
-              "Raman Gupta",
-              "Remko Popma",
-              "Ron Grabowski",
-              "Scott Deboy",
-              "Spotify",
-              "The Apache Software Foundation",
-              "Volkan Yazıcı"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "The Apache Log4j binding between Log4j 2 API and SLF4J.",
-            "homepage_url": "https://logging.apache.org/log4j/2.x/log4j-to-slf4j/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-to-slf4j/2.20.0/log4j-to-slf4j-2.20.0.jar",
-              "hash": {
-                "value": "d37f81f8978e2672bc32c82712ab4b3f66624adc",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apache/logging/log4j/log4j-to-slf4j/2.20.0/log4j-to-slf4j-2.20.0-sources.jar",
-              "hash": {
-                "value": "eb8b060c8d3934a8cca8a5b99a7b1bb94a7db019",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/apache/logging-log4j2.git",
-              "revision": "log4j-2.20.0-rc1",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/apache/logging-log4j2.git",
-              "revision": "log4j-2.20.0-rc1",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.apiguardian:apiguardian-api:1.1.2",
-            "purl": "pkg:maven/org.apiguardian/apiguardian-api@1.1.2",
-            "authors": [
-              "@API Guardian Team"
-            ],
-            "declared_licenses": [
-              "The Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "@API Guardian",
-            "homepage_url": "https://github.com/apiguardian-team/apiguardian",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar",
-              "hash": {
-                "value": "a231e0d844d2721b0fa1b238006d15c6ded6842a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2-sources.jar",
-              "hash": {
-                "value": "e0787a997746ac32639e0bf3cb27af8dce8a3428",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/apiguardian-team/apiguardian.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/apiguardian-team/apiguardian.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.assertj:assertj-core:3.24.2",
-            "purl": "pkg:maven/org.assertj/assertj-core@3.24.2",
-            "authors": [
-              "AssertJ",
-              "Christian Rösch",
-              "Erhard Pointl",
-              "Florent Biville",
-              "Joel Costigliola",
-              "Julien Roy",
-              "Pascal Schumacher",
-              "Patrick Allain",
-              "Régis Pouiller",
-              "Stefano Cordio"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Rich and fluent assertions for testing in Java",
-            "homepage_url": "https://assertj.github.io/doc/#assertj-core",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.24.2/assertj-core-3.24.2.jar",
-              "hash": {
-                "value": "ebbf338e33f893139459ce5df023115971c2786f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/assertj/assertj-core/3.24.2/assertj-core-3.24.2-sources.jar",
-              "hash": {
-                "value": "76c425ccc878f91e347fa3cb0d686772679b66e2",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/assertj/assertj.git",
-              "revision": "assertj-build-3.24.2",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/assertj/assertj.git",
-              "revision": "assertj-build-3.24.2",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.hamcrest:hamcrest:2.2",
-            "purl": "pkg:maven/org.hamcrest/hamcrest@2.2",
-            "authors": [
-              "Joe Walnes",
-              "Nat Pryce",
-              "Steve Freeman"
-            ],
-            "declared_licenses": [
-              "BSD License 3"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "BSD-3-Clause",
-              "mapped": {
-                "BSD License 3": "BSD-3-Clause"
-              }
-            },
-            "description": "Core API and libraries of hamcrest matcher framework.",
-            "homepage_url": "http://hamcrest.org/JavaHamcrest/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/2.2/hamcrest-2.2.jar",
-              "hash": {
-                "value": "1820c0968dba3a11a1b30669bb1f01978a91dedc",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/2.2/hamcrest-2.2-sources.jar",
-              "hash": {
-                "value": "a0a13cfc629420efb587d954f982c4c6a100da25",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git@github.com:hamcrest/JavaHamcrest.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/hamcrest/JavaHamcrest.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.jupiter:junit-jupiter:5.9.3",
-            "purl": "pkg:maven/org.junit.jupiter/junit-jupiter@5.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-jupiter\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.9.3/junit-jupiter-5.9.3.jar",
-              "hash": {
-                "value": "72e840501e1550e9799c9a5cc9483d7d6b29e0ba",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter/5.9.3/junit-jupiter-5.9.3-sources.jar",
-              "hash": {
-                "value": "5fd01c33132462aab3905cb74bd1097a713ab91a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.jupiter:junit-jupiter-api:5.9.3",
-            "purl": "pkg:maven/org.junit.jupiter/junit-jupiter-api@5.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-jupiter-api\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.9.3/junit-jupiter-api-5.9.3.jar",
-              "hash": {
-                "value": "815818ad6ffcc8d320d8fbdf3d748c753cf83201",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.9.3/junit-jupiter-api-5.9.3-sources.jar",
-              "hash": {
-                "value": "85988e8197299a175eb2576f8f069fc84299a9f4",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.jupiter:junit-jupiter-engine:5.9.3",
-            "purl": "pkg:maven/org.junit.jupiter/junit-jupiter-engine@5.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-jupiter-engine\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.9.3/junit-jupiter-engine-5.9.3.jar",
-              "hash": {
-                "value": "355322b03bf39306a183162cd06626c206f0286b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-engine/5.9.3/junit-jupiter-engine-5.9.3-sources.jar",
-              "hash": {
-                "value": "197892276ba628c4cdca0ab3168f9c24ce6c73f8",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.jupiter:junit-jupiter-params:5.9.3",
-            "purl": "pkg:maven/org.junit.jupiter/junit-jupiter-params@5.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-jupiter-params\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.9.3/junit-jupiter-params-5.9.3.jar",
-              "hash": {
-                "value": "9e2a4bf6016a1975f408a73523392875cff7c26f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-params/5.9.3/junit-jupiter-params-5.9.3-sources.jar",
-              "hash": {
-                "value": "d10dec2ad6dad92cdab830904e9bc4a1de4fd84a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.platform:junit-platform-commons:1.9.3",
-            "purl": "pkg:maven/org.junit.platform/junit-platform-commons@1.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-platform-commons\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.9.3/junit-platform-commons-1.9.3.jar",
-              "hash": {
-                "value": "36b2e26a90c41603be7f0094bee80e3f8a2cd4d4",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.9.3/junit-platform-commons-1.9.3-sources.jar",
-              "hash": {
-                "value": "86401c81baae1d05c5dc76d3e40c1b9397384eda",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.junit.platform:junit-platform-engine:1.9.3",
-            "purl": "pkg:maven/org.junit.platform/junit-platform-engine@1.9.3",
-            "authors": [
-              "Christian Stein",
-              "Johannes Link",
-              "Juliette de Rancourt",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "Eclipse Public License v2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "EPL-2.0",
-              "mapped": {
-                "Eclipse Public License v2.0": "EPL-2.0"
-              }
-            },
-            "description": "Module \"junit-platform-engine\" of JUnit 5.",
-            "homepage_url": "https://junit.org/junit5/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.9.3/junit-platform-engine-1.9.3.jar",
-              "hash": {
-                "value": "8616734a190f8d307376aeb7353dba0a2c037a09",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-engine/1.9.3/junit-platform-engine-1.9.3-sources.jar",
-              "hash": {
-                "value": "819f0849cf19b1f46718c36a4fc8406c87bced45",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/junit-team/junit5.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.mockito:mockito-core:5.3.1",
-            "purl": "pkg:maven/org.mockito/mockito-core@5.3.1",
-            "authors": [
-              "Brice Dutheil",
-              "Rafael Winterhalter",
-              "Szczepan Faber",
-              "Tim van der Lippe"
-            ],
-            "declared_licenses": [
-              "The MIT License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "MIT",
-              "mapped": {
-                "The MIT License": "MIT"
-              }
-            },
-            "description": "Mockito mock objects library core API and implementation",
-            "homepage_url": "https://github.com/mockito/mockito",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.3.1/mockito-core-5.3.1.jar",
-              "hash": {
-                "value": "7cac313592a29ae5e29c52c22b15c3ae5ab561b2",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/mockito/mockito-core/5.3.1/mockito-core-5.3.1-sources.jar",
-              "hash": {
-                "value": "cafb8e6597bc015f25eb40141792991f0f39afc2",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "",
-              "url": "",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/mockito/mockito.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.mockito:mockito-junit-jupiter:5.3.1",
-            "purl": "pkg:maven/org.mockito/mockito-junit-jupiter@5.3.1",
-            "authors": [
-              "Brice Dutheil",
-              "Rafael Winterhalter",
-              "Szczepan Faber",
-              "Tim van der Lippe"
-            ],
-            "declared_licenses": [
-              "The MIT License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "MIT",
-              "mapped": {
-                "The MIT License": "MIT"
-              }
-            },
-            "description": "Mockito JUnit 5 support",
-            "homepage_url": "https://github.com/mockito/mockito",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.3.1/mockito-junit-jupiter-5.3.1.jar",
-              "hash": {
-                "value": "d6ac0f6d54addf02def4ba1213f73a15ae6c2308",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/mockito/mockito-junit-jupiter/5.3.1/mockito-junit-jupiter-5.3.1-sources.jar",
-              "hash": {
-                "value": "6aa189452f42167be3dc9ce5ac029df0f15ba0e5",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "",
-              "url": "",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/mockito/mockito.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.objenesis:objenesis:3.3",
-            "purl": "pkg:maven/org.objenesis/objenesis@3.3",
-            "authors": [
-              "Henri Tremblay",
-              "Joe Walnes",
-              "Joe Walnes, Henri Tremblay, Leonardo Mesquita",
-              "Leonardo Mesquita"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "A library for instantiating Java objects",
-            "homepage_url": "http://objenesis.org/objenesis",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3.jar",
-              "hash": {
-                "value": "1049c09f1de4331e8193e579448d0916d75b7631",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/objenesis/objenesis/3.3/objenesis-3.3-sources.jar",
-              "hash": {
-                "value": "5fef34eeee6816b0ba2170755a8a9db7744990c3",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/easymock/objenesis.git",
-              "revision": "3.3",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/easymock/objenesis.git",
-              "revision": "3.3",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.opentest4j:opentest4j:1.2.0",
-            "purl": "pkg:maven/org.opentest4j/opentest4j@1.2.0",
-            "authors": [
-              "Johannes Link",
-              "Marc Philipp",
-              "Matthias Merdes",
-              "Sam Brannen",
-              "Stefan Bechtold"
-            ],
-            "declared_licenses": [
-              "The Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Open Test Alliance for the JVM",
-            "homepage_url": "https://github.com/ota4j-team/opentest4j",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar",
-              "hash": {
-                "value": "28c11eb91f9b6d8e200631d46e20a7f407f2a046",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0-sources.jar",
-              "hash": {
-                "value": "41d55b3c2254de9837b4ec8923cbd371b8a7eab5",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/ota4j-team/opentest4j.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/ota4j-team/opentest4j.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.ow2.asm:asm:9.3",
-            "purl": "pkg:maven/org.ow2.asm/asm@9.3",
-            "authors": [
-              "Eric Bruneton",
-              "Eugene Kuleshov",
-              "OW2",
-              "Remi Forax"
-            ],
-            "declared_licenses": [
-              "BSD-3-Clause"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "BSD-3-Clause"
-            },
-            "description": "ASM, a very small and fast Java bytecode manipulation framework",
-            "homepage_url": "http://asm.ow2.io/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.3/asm-9.3.jar",
-              "hash": {
-                "value": "8e6300ef51c1d801a7ed62d07cd221aca3a90640",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.3/asm-9.3-sources.jar",
-              "hash": {
-                "value": "ce26e415ccafa10c6624a07bdb38d969110f568f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://gitlab.ow2.org/asm/asm/",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://gitlab.ow2.org/asm/asm",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.skyscreamer:jsonassert:1.5.1",
-            "purl": "pkg:maven/org.skyscreamer/jsonassert@1.5.1",
-            "authors": [
-              "Carter Page",
-              "Corby Page",
-              "Solomon Duskis"
-            ],
-            "declared_licenses": [
-              "The Apache Software License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache Software License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "A library to develop RESTful but flexible APIs",
-            "homepage_url": "https://github.com/skyscreamer/JSONassert",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.1/jsonassert-1.5.1.jar",
-              "hash": {
-                "value": "6d842d0faf4cf6725c509a5e5347d319ee0431c3",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/skyscreamer/jsonassert/1.5.1/jsonassert-1.5.1-sources.jar",
-              "hash": {
-                "value": "56cfa73a7ab13fbb8d433570add90f087d40e243",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git@github.com:skyscreamer/JSONassert.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/skyscreamer/JSONassert.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.slf4j:jul-to-slf4j:2.0.7",
-            "purl": "pkg:maven/org.slf4j/jul-to-slf4j@2.0.7",
-            "authors": [
-              "Ceki Gulcu",
-              "QOS.ch"
-            ],
-            "declared_licenses": [
-              "MIT License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "MIT",
-              "mapped": {
-                "MIT License": "MIT"
-              }
-            },
-            "description": "JUL to SLF4J bridge",
-            "homepage_url": "http://www.slf4j.org",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/slf4j/jul-to-slf4j/2.0.7/jul-to-slf4j-2.0.7.jar",
-              "hash": {
-                "value": "a48f44aeaa8a5ddc347007298a28173ac1fbbd8b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/slf4j/jul-to-slf4j/2.0.7/jul-to-slf4j-2.0.7-sources.jar",
-              "hash": {
-                "value": "9c8390d2f8b7b09f8f9e80f2ecda55ec60d00d38",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/slf4j.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/slf4j.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.slf4j:slf4j-api:2.0.7",
-            "purl": "pkg:maven/org.slf4j/slf4j-api@2.0.7",
-            "authors": [
-              "Ceki Gulcu",
-              "QOS.ch"
-            ],
-            "declared_licenses": [
-              "MIT License"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "MIT",
-              "mapped": {
-                "MIT License": "MIT"
-              }
-            },
-            "description": "The slf4j API",
-            "homepage_url": "http://www.slf4j.org",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar",
-              "hash": {
-                "value": "41eb7184ea9d556f23e18b5cb99cad1f8581fc00",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7-sources.jar",
-              "hash": {
-                "value": "f887f95694cd20d51a062446b6e3d09dd02d98ff",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/slf4j.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/qos-ch/slf4j.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-aop:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-aop@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring AOP",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.0.9/spring-aop-6.0.9.jar",
-              "hash": {
-                "value": "8c1025bf9c1dc66f5268639866b5a45ed9bc62ef",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-aop/6.0.9/spring-aop-6.0.9-sources.jar",
-              "hash": {
-                "value": "3d30ea425aaa15b74e7b7222e1e1a8627c147157",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-beans:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-beans@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Beans",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.0.9/spring-beans-6.0.9.jar",
-              "hash": {
-                "value": "745619eee32c8ead88a21c97748d2416f1db8dd9",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-beans/6.0.9/spring-beans-6.0.9-sources.jar",
-              "hash": {
-                "value": "b0ec41d8bf0b5029e032cac9aa78af006faddf1f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-context:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-context@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Context",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.0.9/spring-context-6.0.9.jar",
-              "hash": {
-                "value": "be88c57829b9ec038774b47c241ac45673352a55",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-context/6.0.9/spring-context-6.0.9-sources.jar",
-              "hash": {
-                "value": "1e1be018969e751e4c8da63399195b367ede22f4",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-core:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-core@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Core",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.0.9/spring-core-6.0.9.jar",
-              "hash": {
-                "value": "284ed111fa0b49b29f6fea6ac0afa402b809e427",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-core/6.0.9/spring-core-6.0.9-sources.jar",
-              "hash": {
-                "value": "29f56137b41bb83d7f85b974d89cb973ad7772d1",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-expression:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-expression@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Expression Language (SpEL)",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.0.9/spring-expression-6.0.9.jar",
-              "hash": {
-                "value": "f50a1df7ed038ee7ca85528aff652cef4ff4883b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-expression/6.0.9/spring-expression-6.0.9-sources.jar",
-              "hash": {
-                "value": "e8ab11caa78f1db79cf2e9521565e91e7b439c1d",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-jcl:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-jcl@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Commons Logging Bridge",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.0.9/spring-jcl-6.0.9.jar",
-              "hash": {
-                "value": "88d9ddfc6bbbf4047c2a8de8de94a425b06f636a",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-jcl/6.0.9/spring-jcl-6.0.9-sources.jar",
-              "hash": {
-                "value": "6a417a5afff2c2dc8e71d54e3cc6f943a42dd4c3",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework:spring-test:6.0.9",
-            "purl": "pkg:maven/org.springframework/spring-test@6.0.9",
-            "authors": [
-              "Juergen Hoeller",
-              "Spring IO"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring TestContext Framework",
-            "homepage_url": "https://github.com/spring-projects/spring-framework",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.0.9/spring-test-6.0.9.jar",
-              "hash": {
-                "value": "f50dd9d3b153dd2f56fa760f1cf8247f56f1ad45",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/spring-test/6.0.9/spring-test-6.0.9-sources.jar",
-              "hash": {
-                "value": "77e2ed920461577c033b65fb8ab9493d587ae06b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-framework",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-framework.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Boot",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot/3.1.0/spring-boot-3.1.0.jar",
-              "hash": {
-                "value": "efa941e9a2162a3dd8c5e4679f46a24af9e5769f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot/3.1.0/spring-boot-3.1.0-sources.jar",
-              "hash": {
-                "value": "79217b6a643f4bd95a48d2cb254a30cc1912aace",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-autoconfigure:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-autoconfigure@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Boot AutoConfigure",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-autoconfigure/3.1.0/spring-boot-autoconfigure-3.1.0.jar",
-              "hash": {
-                "value": "b06d1f0b08f6f8a2636e364c8941b2dabc4f0b77",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-autoconfigure/3.1.0/spring-boot-autoconfigure-3.1.0-sources.jar",
-              "hash": {
-                "value": "6032b40715d44093aa5cbd3653a78cb8c9b7132e",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-starter:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-starter@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Core starter, including auto-configuration support, logging and YAML",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter/3.1.0/spring-boot-starter-3.1.0.jar",
-              "hash": {
-                "value": "2960a1f899f4ee3eb815dc85986b0428c1a5289f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter/3.1.0/spring-boot-starter-3.1.0-sources.jar",
-              "hash": {
-                "value": "2af67ef8e7b5038f7a6bb518e53183993a03b20b",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "is_metadata_only": true
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-starter-logging:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-starter-logging@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Starter for logging using Logback. Default logging starter",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-logging/3.1.0/spring-boot-starter-logging-3.1.0.jar",
-              "hash": {
-                "value": "4784b6e2adfe32720a4e2c009a62650835bba391",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-logging/3.1.0/spring-boot-starter-logging-3.1.0-sources.jar",
-              "hash": {
-                "value": "b7e9505d518959c41fe88828a329a7bb465c23ae",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "is_metadata_only": true
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-starter-test:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-starter-test@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-test/3.1.0/spring-boot-starter-test-3.1.0.jar",
-              "hash": {
-                "value": "d3586ab09b3377ee5ccd9045ee7e7cae3bd983a7",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-test/3.1.0/spring-boot-starter-test-3.1.0-sources.jar",
-              "hash": {
-                "value": "d26d8c0dbc5a6f1410f617ce6aa4f751b57a093d",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "is_metadata_only": true
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-test:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-test@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Boot Test",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-test/3.1.0/spring-boot-test-3.1.0.jar",
-              "hash": {
-                "value": "dd28c89c37a9e967ad4101c13a3cc420eb5cd1d0",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-test/3.1.0/spring-boot-test-3.1.0-sources.jar",
-              "hash": {
-                "value": "5ac4b7845c5dfcffa2cbc90f096def8097fc08b2",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.springframework.boot:spring-boot-test-autoconfigure:3.1.0",
-            "purl": "pkg:maven/org.springframework.boot/spring-boot-test-autoconfigure@3.1.0",
-            "authors": [
-              "VMware, Inc."
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "Spring Boot Test AutoConfigure",
-            "homepage_url": "https://spring.io/projects/spring-boot",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-test-autoconfigure/3.1.0/spring-boot-test-autoconfigure-3.1.0.jar",
-              "hash": {
-                "value": "3c6f415e73b603ce8d6f635831de8b936297bbde",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-test-autoconfigure/3.1.0/spring-boot-test-autoconfigure-3.1.0-sources.jar",
-              "hash": {
-                "value": "276a0e37ea7ad4fb6b53800fc3010a3f8972af90",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "https://github.com/spring-projects/spring-boot.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.xmlunit:xmlunit-core:2.9.1",
-            "purl": "pkg:maven/org.xmlunit/xmlunit-core@2.9.1",
-            "authors": [
-              "XMLUnit"
-            ],
-            "declared_licenses": [
-              "The Apache Software License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "The Apache Software License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "XMLUnit for Java",
-            "homepage_url": "https://www.xmlunit.org/",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.9.1/xmlunit-core-2.9.1.jar",
-              "hash": {
-                "value": "e5833662d9a1279a37da3ef6f62a1da29fcd68c4",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/xmlunit/xmlunit-core/2.9.1/xmlunit-core-2.9.1-sources.jar",
-              "hash": {
-                "value": "8ef88e77c158cdc17de55ad94e1e7e7972a91bd6",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "git@github.com:xmlunit/xmlunit.git",
-              "revision": "",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "ssh://git@github.com/xmlunit/xmlunit.git",
-              "revision": "",
-              "path": ""
-            }
-          },
-          {
-            "id": "Maven:org.yaml:snakeyaml:1.33",
-            "purl": "pkg:maven/org.yaml/snakeyaml@1.33",
-            "authors": [
-              "Alexander Maslov",
-              "Andrey Somov"
-            ],
-            "declared_licenses": [
-              "Apache License, Version 2.0"
-            ],
-            "declared_licenses_processed": {
-              "spdx_expression": "Apache-2.0",
-              "mapped": {
-                "Apache License, Version 2.0": "Apache-2.0"
-              }
-            },
-            "description": "YAML 1.1 parser and emitter for Java",
-            "homepage_url": "https://bitbucket.org/snakeyaml/snakeyaml",
-            "binary_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar",
-              "hash": {
-                "value": "2cd0a87ff7df953f810c344bdf2fe3340b954c69",
-                "algorithm": "SHA-1"
-              }
-            },
-            "source_artifact": {
-              "url": "https://repo.maven.apache.org/maven2/org/yaml/snakeyaml/1.33/snakeyaml-1.33-sources.jar",
-              "hash": {
-                "value": "97257a0e34679175cc00444a64fa42d6bb53e23f",
-                "algorithm": "SHA-1"
-              }
-            },
-            "vcs": {
-              "type": "Git",
-              "url": "http://bitbucket.org/snakeyaml/snakeyaml",
-              "revision": "snakeyaml-1.33",
-              "path": ""
-            },
-            "vcs_processed": {
-              "type": "Git",
-              "url": "http://bitbucket.org/snakeyaml/snakeyaml",
-              "revision": "snakeyaml-1.33",
-              "path": ""
-            }
-          }
-        ],
-        "dependency_graphs": {
-          "Maven": {
-            "packages": [
-              "Maven:ch.qos.logback:logback-classic:1.4.7",
-              "Maven:ch.qos.logback:logback-core:1.4.7",
-              "Maven:com.jayway.jsonpath:json-path:2.8.0",
-              "Maven:com.vaadin.external.google:android-json:0.0.20131108.vaadin1",
-              "Maven:jakarta.activation:jakarta.activation-api:2.1.2",
-              "Maven:jakarta.annotation:jakarta.annotation-api:2.1.1",
-              "Maven:jakarta.xml.bind:jakarta.xml.bind-api:4.0.0",
-              "Maven:net.bytebuddy:byte-buddy-agent:1.14.4",
-              "Maven:net.bytebuddy:byte-buddy:1.14.4",
-              "Maven:net.minidev:accessors-smart:2.4.9",
-              "Maven:net.minidev:json-smart:2.4.10",
-              "Maven:org.apache.logging.log4j:log4j-api:2.14.1",
-              "Maven:org.apache.logging.log4j:log4j-core:2.14.1",
-              "Maven:org.apache.logging.log4j:log4j-to-slf4j:2.20.0",
-              "Maven:org.apiguardian:apiguardian-api:1.1.2",
-              "Maven:org.assertj:assertj-core:3.24.2",
-              "Maven:org.hamcrest:hamcrest:2.2",
-              "Maven:org.junit.jupiter:junit-jupiter-api:5.9.3",
-              "Maven:org.junit.jupiter:junit-jupiter-engine:5.9.3",
-              "Maven:org.junit.jupiter:junit-jupiter-params:5.9.3",
-              "Maven:org.junit.jupiter:junit-jupiter:5.9.3",
-              "Maven:org.junit.platform:junit-platform-commons:1.9.3",
-              "Maven:org.junit.platform:junit-platform-engine:1.9.3",
-              "Maven:org.mockito:mockito-core:5.3.1",
-              "Maven:org.mockito:mockito-junit-jupiter:5.3.1",
-              "Maven:org.objenesis:objenesis:3.3",
-              "Maven:org.opentest4j:opentest4j:1.2.0",
-              "Maven:org.ow2.asm:asm:9.3",
-              "Maven:org.skyscreamer:jsonassert:1.5.1",
-              "Maven:org.slf4j:jul-to-slf4j:2.0.7",
-              "Maven:org.slf4j:slf4j-api:2.0.7",
-              "Maven:org.springframework.boot:spring-boot-autoconfigure:3.1.0",
-              "Maven:org.springframework.boot:spring-boot-starter-logging:3.1.0",
-              "Maven:org.springframework.boot:spring-boot-starter-test:3.1.0",
-              "Maven:org.springframework.boot:spring-boot-starter:3.1.0",
-              "Maven:org.springframework.boot:spring-boot-test-autoconfigure:3.1.0",
-              "Maven:org.springframework.boot:spring-boot-test:3.1.0",
-              "Maven:org.springframework.boot:spring-boot:3.1.0",
-              "Maven:org.springframework:spring-aop:6.0.9",
-              "Maven:org.springframework:spring-beans:6.0.9",
-              "Maven:org.springframework:spring-context:6.0.9",
-              "Maven:org.springframework:spring-core:6.0.9",
-              "Maven:org.springframework:spring-expression:6.0.9",
-              "Maven:org.springframework:spring-jcl:6.0.9",
-              "Maven:org.springframework:spring-test:6.0.9",
-              "Maven:org.xmlunit:xmlunit-core:2.9.1",
-              "Maven:org.yaml:snakeyaml:1.33"
-            ],
-            "scopes": {
-              "com.example:demo:0.0.1-SNAPSHOT:compile": [
-                {
-                  "root": 11
-                },
-                {
-                  "root": 12
-                },
-                {
-                  "root": 34
-                }
-              ],
-              "com.example:demo:0.0.1-SNAPSHOT:test": [
-                {
-                  "root": 33
-                }
-              ]
-            },
-            "nodes": [
-              {
-                "pkg": 11
-              },
-              {
-                "pkg": 12
-              },
-              {
-                "pkg": 38
-              },
-              {
-                "pkg": 39
-              },
-              {
-                "pkg": 42
-              },
-              {
-                "pkg": 40
-              },
-              {
-                "pkg": 37
-              },
-              {
-                "pkg": 31
-              },
-              {
-                "pkg": 1
-              },
-              {},
-              {
-                "pkg": 13
-              },
-              {
-                "pkg": 29
-              },
-              {
-                "pkg": 32
-              },
-              {
-                "pkg": 5
-              },
-              {
-                "pkg": 43
-              },
-              {
-                "pkg": 41
-              },
-              {
-                "pkg": 46
-              },
-              {
-                "pkg": 34
-              },
-              {
-                "pkg": 36
-              },
-              {
-                "pkg": 35
-              },
-              {
-                "pkg": 30
-              },
-              {
-                "pkg": 2
-              },
-              {
-                "pkg": 4
-              },
-              {
-                "pkg": 6
-              },
-              {
-                "pkg": 27
-              },
-              {
-                "pkg": 9
-              },
-              {
-                "pkg": 10
-              },
-              {
-                "pkg": 8
-              },
-              {
-                "pkg": 15
-              },
-              {
-                "pkg": 16
-              },
-              {
-                "pkg": 26
-              },
-              {
-                "pkg": 21
-              },
-              {
-                "pkg": 14
-              },
-              {
-                "pkg": 17
-              },
-              {
-                "pkg": 19
-              },
-              {
-                "pkg": 22
-              },
-              {
-                "pkg": 18
-              },
-              {
-                "pkg": 20
-              },
-              {
-                "pkg": 7
-              },
-              {
-                "pkg": 25
-              },
-              {
-                "pkg": 23
-              },
-              {
-                "pkg": 24
-              },
-              {
-                "pkg": 3
-              },
-              {
-                "pkg": 28
-              },
-              {
-                "pkg": 44
-              },
-              {
-                "pkg": 45
-              },
-              {
-                "pkg": 33
-              }
-            ],
-            "edges": [
-              {
-                "from": 5,
-                "to": 2
-              },
-              {
-                "from": 5,
-                "to": 3
-              },
-              {
-                "from": 5,
-                "to": 4
-              },
-              {
-                "from": 6,
-                "to": 5
-              },
-              {
-                "from": 9,
-                "to": 8
-              },
-              {
-                "from": 12,
-                "to": 9
-              },
-              {
-                "from": 12,
-                "to": 10
-              },
-              {
-                "from": 12,
-                "to": 11
-              },
-              {
-                "from": 15,
-                "to": 14
-              },
-              {
-                "from": 17,
-                "to": 6
-              },
-              {
-                "from": 17,
-                "to": 7
-              },
-              {
-                "from": 17,
-                "to": 12
-              },
-              {
-                "from": 17,
-                "to": 13
-              },
-              {
-                "from": 17,
-                "to": 15
-              },
-              {
-                "from": 17,
-                "to": 16
-              },
-              {
-                "from": 21,
-                "to": 20
-              },
-              {
-                "from": 23,
-                "to": 22
-              },
-              {
-                "from": 25,
-                "to": 24
-              },
-              {
-                "from": 26,
-                "to": 25
-              },
-              {
-                "from": 28,
-                "to": 27
-              },
-              {
-                "from": 33,
-                "to": 30
-              },
-              {
-                "from": 33,
-                "to": 31
-              },
-              {
-                "from": 33,
-                "to": 32
-              },
-              {
-                "from": 36,
-                "to": 35
-              },
-              {
-                "from": 37,
-                "to": 33
-              },
-              {
-                "from": 37,
-                "to": 34
-              },
-              {
-                "from": 37,
-                "to": 36
-              },
-              {
-                "from": 40,
-                "to": 38
-              },
-              {
-                "from": 40,
-                "to": 39
-              },
-              {
-                "from": 43,
-                "to": 42
-              },
-              {
-                "from": 46,
-                "to": 18
-              },
-              {
-                "from": 46,
-                "to": 19
-              },
-              {
-                "from": 46,
-                "to": 21
-              },
-              {
-                "from": 46,
-                "to": 23
-              },
-              {
-                "from": 46,
-                "to": 26
-              },
-              {
-                "from": 46,
-                "to": 28
-              },
-              {
-                "from": 46,
-                "to": 29
-              },
-              {
-                "from": 46,
-                "to": 37
-              },
-              {
-                "from": 46,
-                "to": 40
-              },
-              {
-                "from": 46,
-                "to": 41
-              },
-              {
-                "from": 46,
-                "to": 43
-              },
-              {
-                "from": 46,
-                "to": 44
-              },
-              {
-                "from": 46,
-                "to": 45
-              }
-            ]
-          }
-        }
-      }
-    },
-    "scanner": null,
-    "advisor": {
-      "start_time": "2023-08-03T11:31:06.879395046Z",
-      "end_time": "2023-08-03T11:31:16.911666093Z",
-      "environment": {
-        "ort_version": "DOCKER-SNAPSHOT",
-        "java_version": "17.0.8",
-        "os": "Linux",
-        "processors": 4,
-        "max_memory": 1031798784,
-        "variables": {
-          "JAVA_HOME": "/opt/java/openjdk",
-          "ANDROID_HOME": "/opt/android-sdk"
-        },
-        "tool_versions": {}
-      },
-      "config": {
-        "osv": {
-          "server_url": "https://api-staging.osv.dev"
-        }
-      },
-      "results": {
-        "advisor_results": {
-          "Maven:ch.qos.logback:logback-classic:1.4.7": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899265259Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:ch.qos.logback:logback-core:1.4.7": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899254301Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:com.jayway.jsonpath:json-path:2.8.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899245718Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:com.vaadin.external.google:android-json:0.0.20131108.vaadin1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899266468Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:jakarta.activation:jakarta.activation-api:2.1.2": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904177676Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:jakarta.annotation:jakarta.annotation-api:2.1.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899255468Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:jakarta.xml.bind:jakarta.xml.bind-api:4.0.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899267676Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:net.bytebuddy:byte-buddy:1.14.4": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904167218Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:net.bytebuddy:byte-buddy-agent:1.14.4": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899253051Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:net.minidev:accessors-smart:2.4.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899247009Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:net.minidev:json-smart:2.4.10": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899257926Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.apache.logging.log4j:log4j-api:2.14.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904176384Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.apache.logging.log4j:log4j-core:2.14.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899270093Z"
-              },
-              "defects": [],
-              "vulnerabilities": [
-                {
-                  "id": "GHSA-7rjr-3q55-vv33",
-                  "summary": "Incomplete fix for Apache Log4j vulnerability",
-                  "description": "# Impact\n\nThe fix to address [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) in Apache Log4j 2.15.0 was incomplete in certain non-default configurations. This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a remote code execution (RCE) attack. \n\n## Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.\n\n# Mitigation\n\nLog4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default. This issue can be mitigated in prior releases (< 2.16.0) by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class).\n\nLog4j 2.15.0 restricts JNDI LDAP lookups to localhost by default. Note that previous mitigations involving configuration such as to set the system property `log4j2.formatMsgNoLookups` to `true` do NOT mitigate this specific vulnerability.",
-                  "references": [
-                    {
-                      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/security.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.cve.org/CVERecord?id=CVE-2021-44228",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.debian.org/security/2021/dsa-5022",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.kb.cert.org/vuls/id/930724",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.openwall.com/lists/oss-security/2021/12/14/4",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpuapr2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpujan2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpujul2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/14/4",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/15/3",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    },
-                    {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/18/1",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "9.0"
-                    }
-                  ]
-                },
-                {
-                  "id": "GHSA-8489-44mv-ggj8",
-                  "summary": "Improper Input Validation and Injection in Apache Log4j2",
-                  "description": "Apache Log4j2 versions 2.0-beta7 through 2.17.0 (excluding security fix releases 2.3.2 and 2.12.4) are vulnerable to an attack where an attacker with permission to modify the logging configuration file can construct a malicious configuration using a JDBC Appender with a data source referencing a JNDI URI which can execute remote code. This issue is fixed by limiting JNDI data source names to the java protocol in Log4j2 versions 2.17.1, 2.12.4, and 2.3.2.\n\n\n# Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.\n\nThis issue does not impact default configurations of Log4j2 and requires an attacker to have control over the Log4j2 configuration, which reduces the likelihood of being exploited.",
-                  "references": [
-                    {
-                      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44832",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-784507.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://github.com/apache/logging-log4j2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://issues.apache.org/jira/browse/LOG4J2-3293",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://lists.apache.org/thread/s1o5vlo78ypqxnzn6p8zf6t9shtq5143",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://lists.debian.org/debian-lts-announce/2021/12/msg00036.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EVV25FXL4FU5X6X5BSL7RLQ7T6F65MRA/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/T57MPJUW3MA6QGWZRTMCHHMMPQNVKGFC/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
-                    {
-                      "url": "https://security.netapp.com/advisory/ntap-20220104-0001/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
-                    },
+    "code": 200,
+    "result": [
+        {
+            "createdAt": "2023-09-17T17:09:48.141353Z",
+            "cveId": "GHSA-hjrf-2m68-5959",
+            "data": {
+                "description": "# Overview\n\nVersions `<=8.5.1` of `jsonwebtoken` library can be misconfigured so that passing a poorly implemented key retrieval function (referring to the `secretOrPublicKey` argument from the [readme link](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback)) will result in incorrect verification of tokens. There is a possibility of using a different algorithm and key combination in verification  than the one that was used to sign the tokens. Specifically, tokens signed with an asymmetric public key could be verified with a symmetric HS256 algorithm. This can lead to successful validation of forged tokens. \n\n# Am I affected?\n\nYou will be affected if your application is supporting usage of both symmetric key and asymmetric key in jwt.verify() implementation with the same key retrieval function. \n\n# How do I fix it?\n \nUpdate to version 9.0.0.\n\n# Will the fix impact my users?\n\nThere is no impact for end users",
+                "id": "GHSA-hjrf-2m68-5959",
+                "references": [
                     {
-                      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.0",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/security/advisories/GHSA-hjrf-2m68-5959"
                     },
                     {
-                      "url": "https://www.oracle.com/security-alerts/cpuapr2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.0",
+                        "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23541"
                     },
                     {
-                      "url": "https://www.oracle.com/security-alerts/cpujan2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.0",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/commit/e1fa9dcc12054a8681db4e6373da1b30cf7016e3"
                     },
                     {
-                      "url": "https://www.oracle.com/security-alerts/cpujul2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.0",
+                        "url": "https://github.com/auth0/node-jsonwebtoken"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/28/1",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "6.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.0",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/releases/tag/v9.0.0"
                     }
-                  ]
-                },
-                {
-                  "id": "GHSA-jfh8-c2jp-5v3q",
-                  "summary": "Remote code injection in Log4j",
-                  "description": "# Summary\n\nLog4j versions prior to 2.16.0 are subject to a remote code execution vulnerability via the ldap JNDI parser.\nAs per [Apache's Log4j security guide](https://logging.apache.org/log4j/2.x/security.html): Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.16.0, this behavior has been disabled by default.\n\nLog4j version 2.15.0 contained an earlier fix for the vulnerability, but that patch did not disable attacker-controlled JNDI lookups in all situations. For more information, see the `Updated advice for version 2.16.0` section of this advisory.\n\n# Impact\n\nLogging untrusted or user controlled data with a vulnerable version of Log4J may result in Remote Code Execution (RCE) against your application. This includes untrusted data included in logged errors such as exception traces, authentication failures, and other unexpected vectors of user controlled input. \n\n# Affected versions\n\nAny Log4J version prior to v2.15.0 is affected to this specific issue.\n\nThe v1 branch of Log4J which is considered End Of Life (EOL) is vulnerable to other RCE vectors so the recommendation is to still update to 2.16.0 where possible.\n\n## Security releases\nAdditional backports of this fix have been made available in versions 2.3.1, 2.12.2, and 2.12.3\n\n## Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.\n\n# Remediation Advice\n\n## Updated advice for version 2.16.0\n\nThe Apache Logging Services team provided updated mitigation advice upon the release of version 2.16.0, which [disables JNDI by default and completely removes support for message lookups](https://logging.apache.org/log4j/2.x/changes-report.html#a2.16.0).\nEven in version 2.15.0, lookups used in layouts to provide specific pieces of context information will still recursively resolve, possibly triggering JNDI lookups. This problem is being tracked as [CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046). More information is available on the [GitHub Security Advisory for CVE-2021-45046](https://github.com/advisories/GHSA-7rjr-3q55-vv33).\n\nUsers who want to avoid attacker-controlled JNDI lookups but cannot upgrade to 2.16.0 must [ensure that no such lookups resolve to attacker-provided data and ensure that the the JndiLookup class is not loaded](https://issues.apache.org/jira/browse/LOG4J2-3221).\n\nPlease note that Log4J v1 is End Of Life (EOL) and will not receive patches for this issue. Log4J v1 is also vulnerable to other RCE vectors and we recommend you migrate to Log4J 2.16.0 where possible.\n\n",
-                  "references": [
-                    {
-                      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-44228",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/apache/logging-log4j2/pull/608",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/advisories/GHSA-7rjr-3q55-vv33",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/apache/logging-log4j2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/cisagov/log4j-affected-db",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/cisagov/log4j-affected-db/blob/develop/SOFTWARE-LIST.md",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/nu11secur1ty/CVE-mitre/tree/main/CVE-2021-44228",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://github.com/tangxiaofeng7/apache-log4j-poc",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://issues.apache.org/jira/browse/LOG4J2-3198",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://issues.apache.org/jira/browse/LOG4J2-3201",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://issues.apache.org/jira/browse/LOG4J2-3214",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://issues.apache.org/jira/browse/LOG4J2-3221",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://lists.debian.org/debian-lts-announce/2021/12/msg00007.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/M5CSVUNV4HWZZXGOKNSK6L7RPM7BOKIB/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/VU57UJDCFIASIO35GC55JMKSRXJMCDFM/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/changes-report.html#a2.15.0",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/manual/lookups.html#JndiLookup",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/manual/migration.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/security.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://msrc-blog.microsoft.com/2021/12/11/microsofts-response-to-cve-2021-44228-apache-log4j2/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://security.netapp.com/advisory/ntap-20211210-0007/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://support.apple.com/kb/HT213189",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://twitter.com/kurtseifried/status/1469345530182455296",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.bentley.com/en/common-vulnerability-exposure/be-2022-0001",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.debian.org/security/2021/dsa-5020",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.kb.cert.org/vuls/id/930724",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.nu11secur1ty.com/2021/12/cve-2021-44228.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpuapr2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpujan2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165225/Apache-Log4j2-2.14.1-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165260/VMware-Security-Advisory-2021-0028.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165261/Apache-Log4j2-2.14.1-Information-Disclosure.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165270/Apache-Log4j2-2.14.1-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165281/Log4j2-Log4Shell-Regexes.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165282/Log4j-Payload-Generator.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165306/L4sh-Log4j-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165307/Log4j-Remote-Code-Execution-Word-Bypassing.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165311/log4j-scan-Extensive-Scanner.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165371/VMware-Security-Advisory-2021-0028.4.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165532/Log4Shell-HTTP-Header-Injection.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165642/VMware-vCenter-Server-Unauthenticated-Log4Shell-JNDI-Injection-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/165673/UniFi-Network-Application-Unauthenticated-Log4Shell-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
-                    {
-                      "url": "http://packetstormsecurity.com/files/167794/Open-Xchange-App-Suite-7.10.x-Cross-Site-Scripting-Command-Injection.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
-                    },
+                ],
+                "summary": "jsonwebtoken's insecure implementation of key retrieval function could lead to Forgeable Public/Private Tokens from RSA to HMAC"
+            },
+            "id": "2c783269-2633-4c36-bb26-085c173a67db",
+            "method": "CVSS:3.1",
+            "package": "NPM::jsonwebtoken",
+            "severity": 5,
+            "updatedAt": "2023-09-17T17:09:48.141353Z",
+            "version": "8.5.1"
+        },
+        {
+            "createdAt": "2023-09-17T17:09:48.141353Z",
+            "cveId": "GHSA-c2qf-rxjj-qqgw",
+            "data": {
+                "description": "Versions of the package semver before 7.5.2 on the 7.x branch, before 6.3.1 on the 6.x branch, and all other versions before 5.7.2 are vulnerable to Regular Expression Denial of Service (ReDoS) via the function new Range, when untrusted user data is provided as a range.",
+                "id": "GHSA-c2qf-rxjj-qqgw",
+                "references": [
                     {
-                      "url": "http://packetstormsecurity.com/files/167917/MobileIron-Log4Shell-Remote-Command-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-25883"
                     },
                     {
-                      "url": "http://packetstormsecurity.com/files/171626/AD-Manager-Plus-7122-Remote-Code-Execution.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/pull/564"
                     },
                     {
-                      "url": "http://seclists.org/fulldisclosure/2022/Dec/2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/pull/585"
                     },
                     {
-                      "url": "http://seclists.org/fulldisclosure/2022/Jul/11",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/pull/593"
                     },
                     {
-                      "url": "http://seclists.org/fulldisclosure/2022/Mar/23",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/commit/2f8fd41487acf380194579ecb6f8b1bbfe116be0"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/10/1",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/commit/717534ee353682f3bcf33e60a8af4292626d4441"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/10/2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/commit/928e56d21150da0413a3333a3148b20e741a920c"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/10/3",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/13/1",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/blob/main/classes/range.js#L97-L104"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/13/2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/blob/main/internal/re.js#L138"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/14/4",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://github.com/npm/node-semver/blob/main/internal/re.js#L160"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/15/3",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "10.0"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "5.3",
+                        "url": "https://security.snyk.io/vuln/SNYK-JS-SEMVER-3247795"
                     }
-                  ]
-                },
-                {
-                  "id": "GHSA-p6xc-xr62-6r2g",
-                  "summary": "Apache Log4j2 vulnerable to Improper Input Validation and Uncontrolled Recursion",
-                  "description": "Apache Log4j2 versions 2.0-alpha1 through 2.16.0 (excluding 2.12.3) did not protect from uncontrolled recursion from self-referential lookups. This allows an attacker with control over Thread Context Map data to cause a denial of service when a crafted string is interpreted. This issue was fixed in Log4j 2.17.0 and 2.12.3.\n\n\n# Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.",
-                  "references": [
-                    {
-                      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45105",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-501673.pdf",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://lists.debian.org/debian-lts-announce/2021/12/msg00017.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://logging.apache.org/log4j/2.x/security.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://security.netapp.com/advisory/ntap-20211218-0001/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://www.debian.org/security/2021/dsa-5024",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://www.kb.cert.org/vuls/id/930724",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
-                    {
-                      "url": "https://www.oracle.com/security-alerts/cpuapr2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
-                    },
+                ],
+                "summary": "semver vulnerable to Regular Expression Denial of Service"
+            },
+            "id": "a3d2f9a2-597c-49b8-becf-14f91b95a9b9",
+            "method": "CVSS:3.1",
+            "package": "NPM::semver",
+            "severity": 5.3,
+            "updatedAt": "2023-09-17T17:09:48.141353Z",
+            "version": "5.7.1"
+        },
+        {
+            "createdAt": "2023-09-17T17:09:48.141353Z",
+            "cveId": "GHSA-qwph-4952-7xr6",
+            "data": {
+                "description": "# Overview\n\nIn versions <=8.5.1 of jsonwebtoken library, lack of algorithm definition and a falsy secret or key in the `jwt.verify()` function can lead to signature validation bypass due to defaulting to the `none` algorithm for signature verification.\n\n# Am I affected?\nYou will be affected if all the following are true in the `jwt.verify()` function:\n- a token with no signature is received\n- no algorithms are specified \n- a falsy (e.g. null, false, undefined) secret or key is passed \n\n# How do I fix it?\n \nUpdate to version 9.0.0 which removes the default support for the none algorithm in the `jwt.verify()` method. \n\n# Will the fix impact my users?\n\nThere will be no impact, if you update to version 9.0.0 and you don’t need to allow for the `none` algorithm. If you need 'none' algorithm, you have to explicitly specify that in `jwt.verify()` options.\n",
+                "id": "GHSA-qwph-4952-7xr6",
+                "references": [
                     {
-                      "url": "https://www.oracle.com/security-alerts/cpujan2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "6.4",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/security/advisories/GHSA-qwph-4952-7xr6"
                     },
                     {
-                      "url": "https://www.oracle.com/security-alerts/cpujul2022.html",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "6.4",
+                        "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23540"
                     },
                     {
-                      "url": "https://www.zerodayinitiative.com/advisories/ZDI-21-1541/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "6.4",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/commit/e1fa9dcc12054a8681db4e6373da1b30cf7016e3"
                     },
                     {
-                      "url": "http://www.openwall.com/lists/oss-security/2021/12/19/1",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.6"
+                        "scoring_system": "CVSS:3.1",
+                        "severity": "6.4",
+                        "url": "https://github.com/auth0/node-jsonwebtoken"
                     }
-                  ]
-                }
-              ]
-            }
-          ],
-          "Maven:org.apache.logging.log4j:log4j-to-slf4j:2.20.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904171176Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.apiguardian:apiguardian-api:1.1.2": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904161884Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.assertj:assertj-core:3.24.2": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899248218Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.hamcrest:hamcrest:2.2": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899256718Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.jupiter:junit-jupiter:5.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904168551Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.jupiter:junit-jupiter-api:5.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904164468Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.jupiter:junit-jupiter-engine:5.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904173884Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.jupiter:junit-jupiter-params:5.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904175093Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.platform:junit-platform-commons:1.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904305801Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.junit.platform:junit-platform-engine:1.9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899251884Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.mockito:mockito-core:5.3.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899262718Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.mockito:mockito-junit-jupiter:5.3.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899249384Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.objenesis:objenesis:3.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904153134Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.opentest4j:opentest4j:1.2.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904307634Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.ow2.asm:asm:9.3": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899259093Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.skyscreamer:jsonassert:1.5.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904160426Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.slf4j:jul-to-slf4j:2.0.7": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899261509Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.slf4j:slf4j-api:2.0.7": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899236593Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-aop:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899260301Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-beans:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899250676Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-context:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904158634Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-core:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904165843Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-expression:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899263926Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-jcl:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904172509Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework:spring-test:6.0.9": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904163259Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899239593Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-autoconfigure:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899244468Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-starter:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899243301Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-starter-logging:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899242093Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-starter-test:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899268884Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-test:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899174051Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.springframework.boot:spring-boot-test-autoconfigure:3.1.0": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904169843Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.xmlunit:xmlunit-core:2.9.1": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.899240843Z"
-              },
-              "defects": [],
-              "vulnerabilities": []
-            }
-          ],
-          "Maven:org.yaml:snakeyaml:1.33": [
-            {
-              "advisor": {
-                "name": "OSV",
-                "capabilities": [
-                  "VULNERABILITIES"
-                ]
-              },
-              "summary": {
-                "start_time": "2023-08-03T11:31:06.977155004Z",
-                "end_time": "2023-08-03T11:31:16.904178968Z"
-              },
-              "defects": [],
-              "vulnerabilities": [
-                {
-                  "id": "GHSA-mjmj-j48q-9wg2",
-                  "summary": "SnakeYaml Constructor Deserialization Remote Code Execution",
-                  "description": "### Summary\nSnakeYaml's `Constructor` class, which inherits from `SafeConstructor`, allows any type be deserialized given the following line:\n\nnew Yaml(new Constructor(TestDataClass.class)).load(yamlContent);\n\nTypes do not have to match the types of properties in the target class. A `ConstructorException` is thrown, but only after a malicious payload is deserialized.\n\n### Severity\nHigh, lack of type checks during deserialization allows remote code execution.\n\n### Proof of Concept\nExecute `bash run.sh`. The PoC uses Constructor to deserialize a payload\nfor RCE. RCE is demonstrated by using a payload which performs a http request to\nhttp://127.0.0.1:8000.\n\nExample output of successful run of proof of concept:\n\n```\n$ bash run.sh\n\n[+] Downloading snakeyaml if needed\n[+] Starting mock HTTP server on 127.0.0.1:8000 to demonstrate RCE\nnc: no process found\n[+] Compiling and running Proof of Concept, which a payload that sends a HTTP request to mock web server.\n[+] An exception is expected.\nException:\nCannot create property=payload for JavaBean=Main$TestDataClass@3cbbc1e0\n in 'string', line 1, column 1:\n    payload: !!javax.script.ScriptEn ... \n    ^\nCan not set java.lang.String field Main$TestDataClass.payload to javax.script.ScriptEngineManager\n in 'string', line 1, column 10:\n    payload: !!javax.script.ScriptEngineManag ... \n             ^\n\n\tat org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:291)\n\tat org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:172)\n\tat org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:332)\n\tat org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:230)\n\tat org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:220)\n\tat org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:174)\n\tat org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:158)\n\tat org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:491)\n\tat org.yaml.snakeyaml.Yaml.load(Yaml.java:416)\n\tat Main.main(Main.java:37)\nCaused by: java.lang.IllegalArgumentException: Can not set java.lang.String field Main$TestDataClass.payload to javax.script.ScriptEngineManager\n\tat java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)\n\tat java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)\n\tat java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)\n\tat java.base/java.lang.reflect.Field.set(Field.java:780)\n\tat org.yaml.snakeyaml.introspector.FieldProperty.set(FieldProperty.java:44)\n\tat org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:286)\n\t... 9 more\n[+] Dumping Received HTTP Request. Will not be empty if PoC worked\nGET /proof-of-concept HTTP/1.1\nUser-Agent: Java/11.0.14\nHost: localhost:8000\nAccept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\nConnection: keep-alive\n```\n\n### Further Analysis\nPotential mitigations include, leveraging SnakeYaml's SafeConstructor while parsing untrusted content.\n\nSee https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64581479 for discussion on the subject.\n\nA fix was released in version 2.0. See https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64876314 for more information.\n\n### Timeline\n**Date reported**: 4/11/2022\n**Date fixed**: \n**Date disclosed**: 10/13/2022",
-                  "references": [
-                    {
-                      "url": "https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-1471",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/commits/5014df1a36f50aca54405bb8433bc99a8847f758",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/commits/acc44099f5f4af26ff86b4e4e4cc1c874e2dc5c4",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64581479",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64634374",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/issues/561/cve-2022-1471-vulnerability-in#comment-64876314",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
-                    {
-                      "url": "https://bitbucket.org/snakeyaml/snakeyaml/wiki/CVE-2022-1471",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
-                    },
+                ],
+                "summary": "jsonwebtoken vulnerable to signature validation bypass due to insecure default algorithm in jwt.verify()"
+            },
+            "id": "a818368b-031e-4d57-9886-c058017e3548",
+            "method": "CVSS:3.1",
+            "package": "NPM::jsonwebtoken",
+            "severity": 6.4,
+            "updatedAt": "2023-09-17T17:09:48.141353Z",
+            "version": "8.5.1"
+        },
+        {
+            "createdAt": "2023-09-17T17:09:48.141353Z",
+            "cveId": "GHSA-8cf7-32gw-wr33",
+            "data": {
+                "description": "# Overview\n\nVersions `<=8.5.1` of `jsonwebtoken` library could be misconfigured so that legacy, insecure key types are used for signature verification. For example, DSA keys could be used with the RS256 algorithm. \n\n# Am I affected?\n\nYou are affected if you are using an algorithm and a key type other than the combinations mentioned below\n\n| Key type |  algorithm                                    |\n|----------|------------------------------------------|\n| ec           | ES256, ES384, ES512                      |\n| rsa          | RS256, RS384, RS512, PS256, PS384, PS512 |\n| rsa-pss  | PS256, PS384, PS512                      |\n\nAnd for Elliptic Curve algorithms:\n\n| `alg` | Curve      |\n|-------|------------|\n| ES256 | prime256v1 |\n| ES384 | secp384r1  |\n| ES512 | secp521r1  |\n\n# How do I fix it?\n\nUpdate to version 9.0.0. This version validates for asymmetric key type and algorithm combinations. Please refer to the above mentioned algorithm / key type combinations for the valid secure configuration. After updating to version 9.0.0, If you still intend to continue with signing or verifying tokens using invalid key type/algorithm value combinations, you’ll need to set the `allowInvalidAsymmetricKeyTypes` option  to `true` in the `sign()` and/or `verify()` functions.\n\n# Will the fix impact my users?\n\nThere will be no impact, if you update to version 9.0.0 and you already use a valid secure combination of key type and algorithm. Otherwise,  use the  `allowInvalidAsymmetricKeyTypes` option  to `true` in the `sign()` and `verify()` functions to continue usage of invalid key type/algorithm combination in 9.0.0 for legacy compatibility. \n\n",
+                "id": "GHSA-8cf7-32gw-wr33",
+                "references": [
                     {
-                      "url": "https://github.com/mbechler/marshalsec",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
+                        "scoring_system": null,
+                        "severity": "MODERATE",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/security/advisories/GHSA-8cf7-32gw-wr33"
                     },
                     {
-                      "url": "https://groups.google.com/g/kubernetes-security-announce/c/mwrakFaEdnc",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
+                        "scoring_system": null,
+                        "severity": "MODERATE",
+                        "url": "https://nvd.nist.gov/vuln/detail/CVE-2022-23539"
                     },
                     {
-                      "url": "https://snyk.io/blog/unsafe-deserialization-snakeyaml-java-cve-2022-1471/",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
+                        "scoring_system": null,
+                        "severity": "MODERATE",
+                        "url": "https://github.com/auth0/node-jsonwebtoken/commit/e1fa9dcc12054a8681db4e6373da1b30cf7016e3"
                     },
                     {
-                      "url": "https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true",
-                      "scoring_system": "CVSS:3.1",
-                      "severity": "8.3"
+                        "scoring_system": null,
+                        "severity": "MODERATE",
+                        "url": "https://github.com/auth0/node-jsonwebtoken"
                     }
-                  ]
-                }
-              ]
-            }
-          ]
-        }
-      }
-    },
-    "evaluator": null,
-    "resolved_configuration": {
-      "package_curations": [
-        {
-          "provider": {
-            "id": "DefaultDir"
-          },
-          "curations": []
-        },
-        {
-          "provider": {
-            "id": "DefaultFile"
-          },
-          "curations": []
+                ],
+                "summary": "jsonwebtoken unrestricted key type could lead to legacy keys usage "
+            },
+            "id": "ec43dc75-4f06-4272-8df8-79b3c58ea8fd",
+            "method": "unknown",
+            "package": "NPM::jsonwebtoken",
+            "severity": null,
+            "updatedAt": "2023-09-17T17:09:48.141353Z",
+            "version": "8.5.1"
         }
-      ]
-    }
-  }
+    ]
 }
diff --git a/tools/db/docker-compose.yml b/tools/db/docker-compose.yml
index 63943795..968084e9 100644
--- a/tools/db/docker-compose.yml
+++ b/tools/db/docker-compose.yml
@@ -1,19 +1,19 @@
 version: '3.7'
 services:
-  db:
-    image: postgres:latest
-    restart: always
-    environment:
-      - POSTGRES_USER=sa
-      - POSTGRES_PASSWORD=password
-      - POSTGRES_DB=dataprovider
-    ports:
-      - "5432:5432"
-  api:
-    build: .
-    restart: always
-    ports:
-      - "3000:3000"
-    command: json-server --watch api.json
-    volumes:
-      - "./api.json:/api.json"
\ No newline at end of file
+    db:
+        image: postgres:latest
+        restart: always
+        environment:
+            - POSTGRES_USER=sa
+            - POSTGRES_PASSWORD=password
+            - POSTGRES_DB=dataprovider
+        ports:
+            - "5432:5432"
+    api:
+        build: .
+        restart: always
+        ports:
+            - "3000:3000"
+        command: json-server --watch api.json
+        volumes:
+            - "./api.json:/api.json"
\ No newline at end of file
-- 
GitLab