mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-19 17:26:51 +00:00
Add request type to be saved with each request
This commit is contained in:
parent
a1e56f1596
commit
4f7f5e4d89
@ -37,6 +37,7 @@ data class Request(
|
|||||||
val pid: String,
|
val pid: String,
|
||||||
val fingerprint: String,
|
val fingerprint: String,
|
||||||
val status: RequestStatus,
|
val status: RequestStatus,
|
||||||
|
val type: RequestType,
|
||||||
val processedAt: Instant = Instant.now(),
|
val processedAt: Instant = Instant.now(),
|
||||||
@Embedded.Nullable var report: Report? = null
|
@Embedded.Nullable var report: Report? = null
|
||||||
)
|
)
|
||||||
@ -57,12 +58,22 @@ interface RequestRepository : CrudRepository<Request, Long> {
|
|||||||
|
|
||||||
fun findByUuidEquals(uuid: String): Optional<Request>
|
fun findByUuidEquals(uuid: String): Optional<Request>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM request GROUP BY status ORDER BY status, count DESC;")
|
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'MTB_FILE' GROUP BY status ORDER BY status, count DESC;")
|
||||||
fun countStates(): List<CountedState>
|
fun countStates(): List<CountedState>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM (" +
|
@Query("SELECT count(*) AS count, status FROM (" +
|
||||||
"SELECT status, rank() OVER (PARTITION BY patient_id ORDER BY processed_at DESC) AS rank FROM request WHERE status NOT IN ('DUPLICATION')" +
|
"SELECT status, rank() OVER (PARTITION BY patient_id ORDER BY processed_at DESC) AS rank FROM request " +
|
||||||
|
"WHERE type = 'MTB_FILE' AND status NOT IN ('DUPLICATION') " +
|
||||||
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;")
|
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;")
|
||||||
fun findPatientUniqueStates(): List<CountedState>
|
fun findPatientUniqueStates(): List<CountedState>
|
||||||
|
|
||||||
|
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'DELETE' GROUP BY status ORDER BY status, count DESC;")
|
||||||
|
fun countDeleteStates(): List<CountedState>
|
||||||
|
|
||||||
|
@Query("SELECT count(*) AS count, status FROM (" +
|
||||||
|
"SELECT status, rank() OVER (PARTITION BY patient_id ORDER BY processed_at DESC) AS rank FROM request " +
|
||||||
|
"WHERE type = 'DELETE'" +
|
||||||
|
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;")
|
||||||
|
fun findPatientUniqueDeleteStates(): List<CountedState>
|
||||||
|
|
||||||
}
|
}
|
@ -24,7 +24,5 @@ enum class RequestStatus(val value: String) {
|
|||||||
WARNING("warning"),
|
WARNING("warning"),
|
||||||
ERROR("error"),
|
ERROR("error"),
|
||||||
UNKNOWN("unknown"),
|
UNKNOWN("unknown"),
|
||||||
DUPLICATION("duplication"),
|
DUPLICATION("duplication")
|
||||||
DELETE_SUCCESS("delete_success"),
|
|
||||||
DELETE_ERROR("delete_error")
|
|
||||||
}
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ETL-Processor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 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
|
||||||
|
* by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package dev.dnpm.etl.processor.monitoring
|
||||||
|
|
||||||
|
enum class RequestType(val value: String) {
|
||||||
|
MTB_FILE("mtb_file"),
|
||||||
|
DELETE("delete"),
|
||||||
|
}
|
@ -26,6 +26,7 @@ import org.springframework.http.HttpHeaders
|
|||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.web.client.RestClientException
|
import org.springframework.web.client.RestClientException
|
||||||
import org.springframework.web.client.RestTemplate
|
import org.springframework.web.client.RestTemplate
|
||||||
|
import org.springframework.web.util.UriComponentsBuilder
|
||||||
|
|
||||||
class RestMtbFileSender(private val restTargetProperties: RestTargetProperties) : MtbFileSender {
|
class RestMtbFileSender(private val restTargetProperties: RestTargetProperties) : MtbFileSender {
|
||||||
|
|
||||||
@ -68,12 +69,12 @@ class RestMtbFileSender(private val restTargetProperties: RestTargetProperties)
|
|||||||
headers.contentType = MediaType.APPLICATION_JSON
|
headers.contentType = MediaType.APPLICATION_JSON
|
||||||
val entityReq = HttpEntity(null, headers)
|
val entityReq = HttpEntity(null, headers)
|
||||||
restTemplate.delete(
|
restTemplate.delete(
|
||||||
restTargetProperties.uri!!,
|
"${restTargetProperties.uri}/${request.patientId}",
|
||||||
entityReq,
|
entityReq,
|
||||||
String::class.java
|
String::class.java
|
||||||
)
|
)
|
||||||
logger.debug("Sent file via RestMtbFileSender")
|
logger.debug("Sent file via RestMtbFileSender")
|
||||||
MtbFileSender.Response(MtbFileSender.ResponseStatus.SUCCESS)
|
return MtbFileSender.Response(MtbFileSender.ResponseStatus.SUCCESS)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
logger.error("Not a valid URI to export to: '{}'", restTargetProperties.uri!!)
|
logger.error("Not a valid URI to export to: '{}'", restTargetProperties.uri!!)
|
||||||
} catch (e: RestClientException) {
|
} catch (e: RestClientException) {
|
||||||
|
@ -21,10 +21,7 @@ package dev.dnpm.etl.processor.web
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
import dev.dnpm.etl.processor.monitoring.Report
|
import dev.dnpm.etl.processor.monitoring.*
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
|
||||||
import dev.dnpm.etl.processor.output.MtbFileSender
|
import dev.dnpm.etl.processor.output.MtbFileSender
|
||||||
import dev.dnpm.etl.processor.pseudonym.PseudonymizeService
|
import dev.dnpm.etl.processor.pseudonym.PseudonymizeService
|
||||||
import org.apache.commons.codec.binary.Base32
|
import org.apache.commons.codec.binary.Base32
|
||||||
@ -62,6 +59,7 @@ class MtbFileController(
|
|||||||
pid = pid,
|
pid = pid,
|
||||||
fingerprint = fingerprint(mtbFile),
|
fingerprint = fingerprint(mtbFile),
|
||||||
status = RequestStatus.DUPLICATION,
|
status = RequestStatus.DUPLICATION,
|
||||||
|
type = RequestType.MTB_FILE,
|
||||||
report = Report("Duplikat erkannt - keine Daten weitergeleitet")
|
report = Report("Duplikat erkannt - keine Daten weitergeleitet")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -106,6 +104,7 @@ class MtbFileController(
|
|||||||
pid = pid,
|
pid = pid,
|
||||||
fingerprint = fingerprint(request.mtbFile),
|
fingerprint = fingerprint(request.mtbFile),
|
||||||
status = requestStatus,
|
status = requestStatus,
|
||||||
|
type = RequestType.MTB_FILE,
|
||||||
report = when (requestStatus) {
|
report = when (requestStatus) {
|
||||||
RequestStatus.ERROR -> Report("Fehler bei der Datenübertragung oder Inhalt nicht verarbeitbar")
|
RequestStatus.ERROR -> Report("Fehler bei der Datenübertragung oder Inhalt nicht verarbeitbar")
|
||||||
RequestStatus.WARNING -> Report("Warnungen über mangelhafte Daten",
|
RequestStatus.WARNING -> Report("Warnungen über mangelhafte Daten",
|
||||||
@ -134,13 +133,37 @@ class MtbFileController(
|
|||||||
val patientPseudonym = pseudonymizeService.patientPseudonym(patientId)
|
val patientPseudonym = pseudonymizeService.patientPseudonym(patientId)
|
||||||
|
|
||||||
val responses = senders.map {
|
val responses = senders.map {
|
||||||
it.send(MtbFileSender.DeleteRequest(requestId, patientPseudonym))
|
val responseStatus = it.send(MtbFileSender.DeleteRequest(requestId, patientPseudonym))
|
||||||
|
when (responseStatus.status) {
|
||||||
|
MtbFileSender.ResponseStatus.SUCCESS -> {
|
||||||
|
logger.info(
|
||||||
|
"Sent delete for Patient '{}' using '{}'",
|
||||||
|
patientPseudonym,
|
||||||
|
it.javaClass.simpleName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
MtbFileSender.ResponseStatus.ERROR -> {
|
||||||
|
logger.error(
|
||||||
|
"Error deleting data for Patient '{}' using '{}'",
|
||||||
|
patientPseudonym,
|
||||||
|
it.javaClass.simpleName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
logger.error(
|
||||||
|
"Unknown result on deleting data for Patient '{}' using '{}'",
|
||||||
|
patientPseudonym,
|
||||||
|
it.javaClass.simpleName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responseStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
val requestStatus = if (responses.map { it.status }.contains(MtbFileSender.ResponseStatus.ERROR)) {
|
val overallRequestStatus = if (responses.map { it.status }.contains(MtbFileSender.ResponseStatus.ERROR)) {
|
||||||
RequestStatus.DELETE_ERROR
|
RequestStatus.ERROR
|
||||||
} else if (responses.map { it.status }.contains(MtbFileSender.ResponseStatus.SUCCESS)) {
|
} else if (responses.map { it.status }.contains(MtbFileSender.ResponseStatus.SUCCESS)) {
|
||||||
RequestStatus.DELETE_SUCCESS
|
RequestStatus.SUCCESS
|
||||||
} else {
|
} else {
|
||||||
RequestStatus.UNKNOWN
|
RequestStatus.UNKNOWN
|
||||||
}
|
}
|
||||||
@ -151,9 +174,10 @@ class MtbFileController(
|
|||||||
patientId = patientPseudonym,
|
patientId = patientPseudonym,
|
||||||
pid = patientId,
|
pid = patientId,
|
||||||
fingerprint = fingerprint(patientPseudonym),
|
fingerprint = fingerprint(patientPseudonym),
|
||||||
status = requestStatus,
|
status = overallRequestStatus,
|
||||||
report = when (requestStatus) {
|
type = RequestType.DELETE,
|
||||||
RequestStatus.DELETE_ERROR -> Report("Fehler bei der Datenübertragung oder Inhalt nicht verarbeitbar")
|
report = when (overallRequestStatus) {
|
||||||
|
RequestStatus.ERROR -> Report("Fehler bei der Datenübertragung oder Inhalt nicht verarbeitbar")
|
||||||
RequestStatus.UNKNOWN -> Report("Keine Informationen")
|
RequestStatus.UNKNOWN -> Report("Keine Informationen")
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@ -168,7 +192,8 @@ class MtbFileController(
|
|||||||
patientId = "???",
|
patientId = "???",
|
||||||
pid = patientId,
|
pid = patientId,
|
||||||
fingerprint = "",
|
fingerprint = "",
|
||||||
status = RequestStatus.DELETE_ERROR,
|
status = RequestStatus.ERROR,
|
||||||
|
type = RequestType.DELETE,
|
||||||
report = Report("Fehler bei der Pseudonymisierung")
|
report = Report("Fehler bei der Pseudonymisierung")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE request ADD COLUMN type varchar(16) not null;
|
||||||
|
UPDATE request SET type = 'MTB_FILE';
|
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE request ADD COLUMN type varchar(16) not null;
|
||||||
|
UPDATE request SET type = 'MTB_FILE';
|
Loading…
x
Reference in New Issue
Block a user