1
0
mirror of https://github.com/pcvolkmer/onco-analytics-monitor.git synced 2025-04-19 11:06:52 +00:00

feat: add interface for ConditionRepository methods

This commit is contained in:
Paul-Christian Volkmer 2024-08-07 20:06:51 +02:00
parent 3dc5d79808
commit 32ac53934f
9 changed files with 107 additions and 24 deletions

View File

@ -1,6 +1,6 @@
package dev.pcvolkmer.oncoanalytics.monitor
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.InMemoryConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Statistics
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@ -18,18 +18,18 @@ class OncoAnalyticsMonitorApplication {
}
@Bean
fun obdsXmlConditionRepository(): ConditionInMemoryRepository {
return ConditionInMemoryRepository()
fun obdsXmlConditionRepository(): InMemoryConditionRepository {
return InMemoryConditionRepository()
}
@Bean
fun fhirObdsConditionRepository(): ConditionInMemoryRepository {
return ConditionInMemoryRepository()
fun fhirObdsConditionRepository(): InMemoryConditionRepository {
return InMemoryConditionRepository()
}
@Bean
fun fhirPseudonymizedConditionRepository(): ConditionInMemoryRepository {
return ConditionInMemoryRepository()
fun fhirPseudonymizedConditionRepository(): InMemoryConditionRepository {
return InMemoryConditionRepository()
}
}

View File

@ -0,0 +1,32 @@
package dev.pcvolkmer.oncoanalytics.monitor.conditions
/**
* Interface declaring a data repository to hold (latest) conditions
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
interface ConditionRepository {
/**
* Save condition if no newer condition (by id and version) is present
*
* @param condition The condition to be saved
* @return Will return true if successful
*/
fun saveIfNewerVersion(condition: Condition): Boolean
/**
* Save condition without any checks
*
* @param condition The condition to be saved
* @return Will return true if successful
*/
fun save(condition: Condition): Boolean
/**
* Return all saved conditions
*/
fun findAll(): List<Condition>
}

View File

@ -2,6 +2,12 @@ package dev.pcvolkmer.oncoanalytics.monitor.conditions
import org.apache.commons.codec.digest.DigestUtils
/**
* Type to be used for the condition ID
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
@JvmInline
value class ConditionId(val value: String) {
companion object {
@ -11,13 +17,30 @@ value class ConditionId(val value: String) {
}
}
/**
* A condition
*
* @property id The conditions unique ID
* @property icd10 The ICD10 code of the related diagnosis
* @property version (if present) The version of the related oBDS message or zero
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
data class Condition(val id: ConditionId, val icd10: String, val version: Int = 0)
class ConditionInMemoryRepository {
/**
* In memory implementation of a ConditionRepository
*
* @author Paul-Christian Volkmer
* @since 0.1.0
* @see ConditionRepository
*/
class InMemoryConditionRepository : ConditionRepository {
private val conditions = mutableMapOf<ConditionId, Condition>()
fun saveIfNewerVersion(condition: Condition): Boolean {
override fun saveIfNewerVersion(condition: Condition): Boolean {
if ((this.conditions[condition.id]?.version ?: 0) < condition.version) {
this.conditions[condition.id] = condition
return true
@ -25,12 +48,12 @@ class ConditionInMemoryRepository {
return false
}
fun save(condition: Condition): Boolean {
override fun save(condition: Condition): Boolean {
this.conditions[condition.id] = condition
return true
}
fun findAll(): List<Condition> {
override fun findAll(): List<Condition> {
return conditions.values.toList()
}

View File

@ -1,8 +1,26 @@
package dev.pcvolkmer.oncoanalytics.monitor.conditions
/**
* A statistics summary
*
* @property name The name of the statistics e.g. the source of data
* @property entries A list of entries containing information for each ICD10 code group
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
data class Statistics(
val name: String,
val entries: List<StatisticsEntry>
)
/**
* A statistics entry
*
* @property name The name of the ICD10 code group
* @property count Number of recognized oBDS or FHIR messages for the OCD10 code group
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
data class StatisticsEntry(val name: String, val count: Int)

View File

@ -1,6 +1,6 @@
package dev.pcvolkmer.oncoanalytics.monitor
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Statistics
import dev.pcvolkmer.oncoanalytics.monitor.conditions.StatisticsEntry
@ -32,7 +32,15 @@ val allKeys = listOf(
"Other"
)
fun fetchStatistics(name: String, source: ConditionInMemoryRepository): Statistics {
/**
* Fetch statistics using given ConditionRepository
*
* @see ConditionRepository
*
* @author Paul-Christian Volkmer
* @since 0.1.0
*/
fun fetchStatistics(name: String, source: ConditionRepository): Statistics {
fun mapIcd10Code(code: String): String {
val c = when (code) {
"D39.1", "D09.0", "D41.4" -> code
@ -72,5 +80,7 @@ fun fetchStatistics(name: String, source: ConditionInMemoryRepository): Statisti
.groupBy { mapIcd10Code(it.icd10) }
.mapValues { it.value.size }
return Statistics(name, allKeys.map { StatisticsEntry(it, 0) }.map { StatisticsEntry(it.name, entries.getOrDefault(it.name, 0)) })
return Statistics(
name,
allKeys.map { StatisticsEntry(it, 0) }.map { StatisticsEntry(it.name, entries.getOrDefault(it.name, 0)) })
}

View File

@ -4,7 +4,7 @@ import ca.uhn.fhir.context.FhirContext
import dev.pcvolkmer.oncoanalytics.monitor.StatisticsSink
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Condition
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionId
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.fetchStatistics
import org.hl7.fhir.r4.model.Bundle
import org.springframework.beans.factory.annotation.Qualifier
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component
@Component
class FhirObdsTopicMonitor(
@Qualifier("fhirObdsConditionRepository")
private val conditionRepository: ConditionInMemoryRepository,
private val conditionRepository: ConditionRepository,
statisticsEventProducer: StatisticsSink,
) : TopicMonitor(statisticsEventProducer) {

View File

@ -4,7 +4,7 @@ import ca.uhn.fhir.context.FhirContext
import dev.pcvolkmer.oncoanalytics.monitor.StatisticsSink
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Condition
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionId
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.fetchStatistics
import org.hl7.fhir.r4.model.Bundle
import org.springframework.beans.factory.annotation.Qualifier
@ -17,7 +17,7 @@ import org.springframework.stereotype.Component
@Component
class FhirPseudonymizedTopicMonitor(
@Qualifier("fhirPseudonymizedConditionRepository")
private val conditionRepository: ConditionInMemoryRepository,
private val conditionRepository: ConditionRepository,
statisticsEventProducer: StatisticsSink,
) : TopicMonitor(statisticsEventProducer) {

View File

@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import dev.pcvolkmer.oncoanalytics.monitor.StatisticsSink
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Condition
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionId
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.fetchStatistics
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.kafka.annotation.KafkaListener
@ -22,7 +22,7 @@ import javax.xml.xpath.XPathFactory
@Component
class ObdsXmlTopicMonitor(
@Qualifier("obdsXmlConditionRepository")
private val conditionRepository: ConditionInMemoryRepository,
private val conditionRepository: ConditionRepository,
private val objectMapper: ObjectMapper,
statisticsEventProducer: StatisticsSink,
) : TopicMonitor(statisticsEventProducer) {

View File

@ -1,6 +1,6 @@
package dev.pcvolkmer.oncoanalytics.monitor.web
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionInMemoryRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.ConditionRepository
import dev.pcvolkmer.oncoanalytics.monitor.conditions.Statistics
import dev.pcvolkmer.oncoanalytics.monitor.fetchStatistics
import org.springframework.beans.factory.annotation.Qualifier
@ -12,11 +12,11 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping(path = ["/statistics"])
class StatisticsController(
@Qualifier("obdsXmlConditionRepository")
private val obdsXmlConditionRepository: ConditionInMemoryRepository,
private val obdsXmlConditionRepository: ConditionRepository,
@Qualifier("fhirObdsConditionRepository")
private val fhirObdsConditionRepository: ConditionInMemoryRepository,
private val fhirObdsConditionRepository: ConditionRepository,
@Qualifier("fhirPseudonymizedConditionRepository")
private val fhirPseudonymizedConditionRepository: ConditionInMemoryRepository,
private val fhirPseudonymizedConditionRepository: ConditionRepository,
) {
@GetMapping(path = ["obdsxml"])