From 7d97365aea81391ae74d64c815261a059bb48c73 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Sun, 6 Apr 2025 13:36:30 +0200 Subject: 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.--- .../etl/processor/input/KafkaInputListenerTest.kt | 84 ++++++++++++++++++++-- .../processor/input/MtbFileRestControllerTest.kt | 36 ++++++++++ 2 files changed, 114 insertions(+), 6 deletions(-) (limited to 'src/test/kotlin/dev') diff --git a/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt index b54a02e..10900a8 100644 --- a/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt +++ b/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt @@ -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()) } -} \ No newline at end of file + @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()) + } + +} diff --git a/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt index ade27b4..faaf778 100644 --- a/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt +++ b/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt @@ -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( -- cgit v1.2.3