1
0
mirror of https://github.com/pcvolkmer/mv64e-etl-processor synced 2025-09-14 01:12:51 +00:00

feat: add endpoint for DNPM-Datamodel V2 using content negotiation (#104)

This simply adds an REST endpoint without proper implementation. The goal is to accept DNPM V2 JSON data.
This commit is contained in:
2025-04-06 13:36:30 +02:00
committed by GitHub
parent 48b1e62e22
commit 7d97365aea
7 changed files with 2446 additions and 13 deletions

View File

@@ -1,7 +1,7 @@
/*
* This file is part of ETL-Processor
*
* Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
* Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import de.ukw.ccc.bwhc.dto.Consent
import de.ukw.ccc.bwhc.dto.MtbFile
import de.ukw.ccc.bwhc.dto.Patient
import dev.dnpm.etl.processor.CustomMediaType
import dev.dnpm.etl.processor.services.RequestProcessor
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.header.internals.RecordHeader
@@ -63,7 +64,15 @@ class KafkaInputListenerTest {
.withConsent(Consent.builder().withStatus(Consent.Status.ACTIVE).build())
.build()
kafkaInputListener.onMessage(ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile)))
kafkaInputListener.onMessage(
ConsumerRecord(
"testtopic",
0,
0,
"",
this.objectMapper.writeValueAsString(mtbFile)
)
)
verify(requestProcessor, times(1)).processMtbFile(any())
}
@@ -75,7 +84,15 @@ class KafkaInputListenerTest {
.withConsent(Consent.builder().withStatus(Consent.Status.REJECTED).build())
.build()
kafkaInputListener.onMessage(ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile)))
kafkaInputListener.onMessage(
ConsumerRecord(
"testtopic",
0,
0,
"",
this.objectMapper.writeValueAsString(mtbFile)
)
)
verify(requestProcessor, times(1)).processDeletion(anyValueClass())
}
@@ -89,7 +106,19 @@ class KafkaInputListenerTest {
val headers = RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
kafkaInputListener.onMessage(
ConsumerRecord("testtopic", 0, 0, -1L, TimestampType.NO_TIMESTAMP_TYPE, -1, -1, "", this.objectMapper.writeValueAsString(mtbFile), headers, Optional.empty())
ConsumerRecord(
"testtopic",
0,
0,
-1L,
TimestampType.NO_TIMESTAMP_TYPE,
-1,
-1,
"",
this.objectMapper.writeValueAsString(mtbFile),
headers,
Optional.empty()
)
)
verify(requestProcessor, times(1)).processMtbFile(any(), anyValueClass())
@@ -104,9 +133,52 @@ class KafkaInputListenerTest {
val headers = RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
kafkaInputListener.onMessage(
ConsumerRecord("testtopic", 0, 0, -1L, TimestampType.NO_TIMESTAMP_TYPE, -1, -1, "", this.objectMapper.writeValueAsString(mtbFile), headers, Optional.empty())
ConsumerRecord(
"testtopic",
0,
0,
-1L,
TimestampType.NO_TIMESTAMP_TYPE,
-1,
-1,
"",
this.objectMapper.writeValueAsString(mtbFile),
headers,
Optional.empty()
)
)
verify(requestProcessor, times(1)).processDeletion(anyValueClass(), anyValueClass())
}
}
@Test
fun shouldNotProcessDnpmV2Request() {
val mtbFile = MtbFile.builder()
.withPatient(Patient.builder().withId("DUMMY_12345678").build())
.withConsent(Consent.builder().withStatus(Consent.Status.REJECTED).build())
.build()
val headers = RecordHeaders(
listOf(
RecordHeader("requestId", UUID.randomUUID().toString().toByteArray()),
RecordHeader("contentType", CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
)
)
kafkaInputListener.onMessage(
ConsumerRecord(
"testtopic",
0,
0,
-1L,
TimestampType.NO_TIMESTAMP_TYPE,
-1,
-1,
"",
this.objectMapper.writeValueAsString(mtbFile),
headers,
Optional.empty()
)
)
verify(requestProcessor, times(0)).processDeletion(anyValueClass(), anyValueClass())
}
}

View File

@@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.input
import com.fasterxml.jackson.databind.ObjectMapper
import de.ukw.ccc.bwhc.dto.*
import dev.dnpm.etl.processor.CustomMediaType
import dev.dnpm.etl.processor.services.RequestProcessor
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
@@ -32,6 +33,7 @@ import org.mockito.Mockito.verify
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.any
import org.mockito.kotlin.anyValueClass
import org.springframework.core.io.ClassPathResource
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.delete
@@ -155,6 +157,40 @@ class MtbFileRestControllerTest {
}
}
@Nested
inner class RequestsForDnpmDataModel21 {
private lateinit var mockMvc: MockMvc
private lateinit var requestProcessor: RequestProcessor
@BeforeEach
fun setup(
@Mock requestProcessor: RequestProcessor
) {
this.requestProcessor = requestProcessor
val controller = MtbFileRestController(requestProcessor)
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
@Test
fun shouldRespondPostRequest() {
val mtbFileContent = ClassPathResource("mv64e-mtb-fake-patient.json").inputStream.readAllBytes().toString(Charsets.UTF_8)
mockMvc.post("/mtb") {
content = mtbFileContent
contentType = CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON
}.andExpect {
status {
isNotImplemented()
}
}
verify(requestProcessor, times(0)).processMtbFile(any())
}
}
companion object {
fun bwhcMtbFileContent(consentStatus: Consent.Status) = MtbFile.builder()
.withPatient(

File diff suppressed because it is too large Load Diff