From 5d07cd79f94affee67ba83c220ae5cdc44b8ed15 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 00:15:37 +0100 Subject: [PATCH 01/14] HL7Server mittels HAPI implementiert und BAR_P05 Nachricht eingelesen. --- pom.xml | 12 +- .../mi/projmi6/hapi2/HL7ConnectionListener2.java | 20 +++ .../mi/projmi6/hapi2/HL7ExceptionHandler2.java | 16 +++ .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 150 +++++++++++++++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 62 +++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java | 33 +++++ src/main/resources/log4j.properties | 8 ++ 7 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java create mode 100644 src/main/resources/log4j.properties diff --git a/pom.xml b/pom.xml index b8b8785..0a4031c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 imi @@ -67,5 +67,15 @@ hapi-structures-v251 2.2 + + org.slf4j + slf4j-log4j12 + 1.6.6 + + + log4j + log4j + 1.2.17 + \ No newline at end of file diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java new file mode 100644 index 0000000..a0dbac6 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java @@ -0,0 +1,20 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.app.Connection; +import ca.uhn.hl7v2.app.ConnectionListener; + +/** + * Created by nils on 20.11.2015. + */ +class HL7ConnectionListener2 implements ConnectionListener { + + @Override + public void connectionReceived(Connection c) { + // System.out.println("New connection: " + c.getRemoteAddress().toString()); + } + + @Override + public void connectionDiscarded(Connection c) { + // System.out.println("Lost connection: " + c.getRemoteAddress().toString()); + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java new file mode 100644 index 0000000..b746016 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java @@ -0,0 +1,16 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; + +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7ExceptionHandler2 implements ReceivingApplicationExceptionHandler { + @Override + public String processException(String incomingMessage, Map incomingMetadata, String outgoingMessage, Exception e) throws HL7Exception { + return outgoingMessage; + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java new file mode 100644 index 0000000..0312971 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java @@ -0,0 +1,150 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.model.AbstractMessage; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import ca.uhn.hl7v2.model.v251.segment.*; +import ca.uhn.hl7v2.protocol.ReceivingApplication; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; +import de.uniluebeck.mi.projmi6.model.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Recever2 implements ReceivingApplication { + private final Class type; + + public HL7Recever2(Class type) { + this.type = type; + } + + + @Override + public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { + + if (type == ADT_A01.class) { + return processADT_A01(message, metadata); + } + if (type == BAR_P05.class) { + return processBAR_P05(message, metadata); + } + + // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + @Override + public boolean canProcess(Message message) { + // TODO: Erstmal alles processen. + return true; + } + + private Message generateACK(Message message) throws HL7Exception { + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { + Patient patient = new Patient(); + List faelle = new ArrayList<>(); + List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); + List ALLE_DIAGNOSEN = new ArrayList<>(); + + BAR_P05 bar_p05 = (BAR_P05) message; + + MSH msh = bar_p05.getMSH(); + PID pid = bar_p05.getPID(); + + patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); + + List visits = bar_p05.getVISITAll(); + + // Ab hier wird es dirty. + for (BAR_P05_VISIT visit : visits) { + + Fall fall = new Fall(); + fall.setPatient(patient); + + List diagnosen = new ArrayList<>(); + List untersuchungen = new ArrayList<>(); + + PV1 pv1 = visit.getPV1(); + // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) + Station station = new Station(); + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + StationsHistorie hist = new StationsHistorie(); + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); + fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); + + List dg1s = visit.getDG1All(); + for (DG1 dg1 : dg1s) { + Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. + // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! + String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... + int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... + Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); + + Diagnose diagnose = new Diagnose(); + diagnose.setIcd10code(icd10code); + diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) + diagnose.setFall(fall); + // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? + + diagnosen.add(diagnose); + } + List procedures = visit.getPROCEDUREAll(); + for (BAR_P05_PROCEDURE procedure : procedures) { + PR1 pr1 = procedure.getPR1(); + Untersuchung untersuchung = new Untersuchung(); + untersuchung.setFall(fall); + + OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... + untersuchung.setOpscode(opscode); + untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); + + String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. + int mitarbid = 1000; // TODO: Siehe oben + untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); + + // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) + + untersuchungen.add(untersuchung); + } + + // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... + faelle.add(fall); + ALLE_DIAGNOSEN.addAll(diagnosen); + ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); + } + + return generateACK(message); + } + + + private Message processADT_A01(Message message, Map metadata) throws HL7Exception { + ADT_A01 adt_a01 = (ADT_A01) message; + System.out.println(adt_a01.toString()); + + return generateACK(message); + } + +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java new file mode 100644 index 0000000..f302d4e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -0,0 +1,62 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.DefaultHapiContext; +import ca.uhn.hl7v2.HapiContext; +import ca.uhn.hl7v2.app.HL7Service; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Server2 { + + private static final int PORT = 1111; + private final HapiContext context; + private final HL7Service server; + private final ThreadPoolExecutor executor; + + public HL7Server2() throws InterruptedException { + executor = new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + context = new DefaultHapiContext(); + context.setExecutorService(executor); + server = context.newServer(PORT, false); + + server.registerApplication("ADT", "A01", new HL7Recever2(ADT_A01.class)); + server.registerApplication("BAR", "P05", new HL7Recever2(BAR_P05.class)); + + server.registerConnectionListener(new HL7ConnectionListener2()); + server.setExceptionHandler(new HL7ExceptionHandler2()); + + //server.startAndWait(); + server.start(); + } + + // TODO: Remove, for testing purpose only! + public static void main(String[] args) throws InterruptedException { + HL7Server2 srv = new HL7Server2(); + for (; ; ) { + + } + //srv.stop(); + //srv.shutdown(); + } + + public void stop() { + if (server != null && server.isRunning()) { + server.stop(); + } + } + + public void shutdown() { + if (executor != null && !executor.isTerminated()) { + executor.shutdown(); + } + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java new file mode 100644 index 0000000..b323e5e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java @@ -0,0 +1,33 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.model.DataTypeException; +import ca.uhn.hl7v2.model.v251.datatype.DTM; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Util2 { + public static LocalDateTime parseLocalDateTime(DTM dtm) { + try { + return LocalDateTime.ofInstant(dtm.getValueAsDate().toInstant(), ZoneId.systemDefault()); + } catch (DataTypeException e) { + e.printStackTrace(); + } + return null; + } + + public static String parseIcd10Code(String icd10code) { + return removeWhitespaces(icd10code).substring(0, 5); + } + + public static String parseOpsCode(String opscode) { + return removeWhitespaces(opscode).substring(0, 7); + } + + private static String removeWhitespaces(String s) { + return s.replaceAll("\\s", ""); + } +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..393e087 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file From 741847b1b420aa4e0f4fab83096a3b3c61582e66 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 00:15:37 +0100 Subject: [PATCH 02/14] HL7Server mittels HAPI implementiert und BAR_P05 Nachricht eingelesen. --- pom.xml | 12 +- .../mi/projmi6/hapi2/HL7ConnectionListener2.java | 20 +++ .../mi/projmi6/hapi2/HL7ExceptionHandler2.java | 16 +++ .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 150 +++++++++++++++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 62 +++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java | 33 +++++ src/main/resources/log4j.properties | 8 ++ 7 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java create mode 100644 src/main/resources/log4j.properties diff --git a/pom.xml b/pom.xml index b8b8785..0a4031c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 imi @@ -67,5 +67,15 @@ hapi-structures-v251 2.2 + + org.slf4j + slf4j-log4j12 + 1.6.6 + + + log4j + log4j + 1.2.17 + \ No newline at end of file diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java new file mode 100644 index 0000000..a0dbac6 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java @@ -0,0 +1,20 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.app.Connection; +import ca.uhn.hl7v2.app.ConnectionListener; + +/** + * Created by nils on 20.11.2015. + */ +class HL7ConnectionListener2 implements ConnectionListener { + + @Override + public void connectionReceived(Connection c) { + // System.out.println("New connection: " + c.getRemoteAddress().toString()); + } + + @Override + public void connectionDiscarded(Connection c) { + // System.out.println("Lost connection: " + c.getRemoteAddress().toString()); + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java new file mode 100644 index 0000000..b746016 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java @@ -0,0 +1,16 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; + +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7ExceptionHandler2 implements ReceivingApplicationExceptionHandler { + @Override + public String processException(String incomingMessage, Map incomingMetadata, String outgoingMessage, Exception e) throws HL7Exception { + return outgoingMessage; + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java new file mode 100644 index 0000000..0312971 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java @@ -0,0 +1,150 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.model.AbstractMessage; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import ca.uhn.hl7v2.model.v251.segment.*; +import ca.uhn.hl7v2.protocol.ReceivingApplication; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; +import de.uniluebeck.mi.projmi6.model.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Recever2 implements ReceivingApplication { + private final Class type; + + public HL7Recever2(Class type) { + this.type = type; + } + + + @Override + public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { + + if (type == ADT_A01.class) { + return processADT_A01(message, metadata); + } + if (type == BAR_P05.class) { + return processBAR_P05(message, metadata); + } + + // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + @Override + public boolean canProcess(Message message) { + // TODO: Erstmal alles processen. + return true; + } + + private Message generateACK(Message message) throws HL7Exception { + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { + Patient patient = new Patient(); + List faelle = new ArrayList<>(); + List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); + List ALLE_DIAGNOSEN = new ArrayList<>(); + + BAR_P05 bar_p05 = (BAR_P05) message; + + MSH msh = bar_p05.getMSH(); + PID pid = bar_p05.getPID(); + + patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); + + List visits = bar_p05.getVISITAll(); + + // Ab hier wird es dirty. + for (BAR_P05_VISIT visit : visits) { + + Fall fall = new Fall(); + fall.setPatient(patient); + + List diagnosen = new ArrayList<>(); + List untersuchungen = new ArrayList<>(); + + PV1 pv1 = visit.getPV1(); + // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) + Station station = new Station(); + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + StationsHistorie hist = new StationsHistorie(); + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); + fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); + + List dg1s = visit.getDG1All(); + for (DG1 dg1 : dg1s) { + Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. + // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! + String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... + int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... + Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); + + Diagnose diagnose = new Diagnose(); + diagnose.setIcd10code(icd10code); + diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) + diagnose.setFall(fall); + // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? + + diagnosen.add(diagnose); + } + List procedures = visit.getPROCEDUREAll(); + for (BAR_P05_PROCEDURE procedure : procedures) { + PR1 pr1 = procedure.getPR1(); + Untersuchung untersuchung = new Untersuchung(); + untersuchung.setFall(fall); + + OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... + untersuchung.setOpscode(opscode); + untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); + + String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. + int mitarbid = 1000; // TODO: Siehe oben + untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); + + // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) + + untersuchungen.add(untersuchung); + } + + // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... + faelle.add(fall); + ALLE_DIAGNOSEN.addAll(diagnosen); + ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); + } + + return generateACK(message); + } + + + private Message processADT_A01(Message message, Map metadata) throws HL7Exception { + ADT_A01 adt_a01 = (ADT_A01) message; + System.out.println(adt_a01.toString()); + + return generateACK(message); + } + +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java new file mode 100644 index 0000000..f302d4e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -0,0 +1,62 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.DefaultHapiContext; +import ca.uhn.hl7v2.HapiContext; +import ca.uhn.hl7v2.app.HL7Service; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Server2 { + + private static final int PORT = 1111; + private final HapiContext context; + private final HL7Service server; + private final ThreadPoolExecutor executor; + + public HL7Server2() throws InterruptedException { + executor = new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + context = new DefaultHapiContext(); + context.setExecutorService(executor); + server = context.newServer(PORT, false); + + server.registerApplication("ADT", "A01", new HL7Recever2(ADT_A01.class)); + server.registerApplication("BAR", "P05", new HL7Recever2(BAR_P05.class)); + + server.registerConnectionListener(new HL7ConnectionListener2()); + server.setExceptionHandler(new HL7ExceptionHandler2()); + + //server.startAndWait(); + server.start(); + } + + // TODO: Remove, for testing purpose only! + public static void main(String[] args) throws InterruptedException { + HL7Server2 srv = new HL7Server2(); + for (; ; ) { + + } + //srv.stop(); + //srv.shutdown(); + } + + public void stop() { + if (server != null && server.isRunning()) { + server.stop(); + } + } + + public void shutdown() { + if (executor != null && !executor.isTerminated()) { + executor.shutdown(); + } + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java new file mode 100644 index 0000000..b323e5e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java @@ -0,0 +1,33 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.model.DataTypeException; +import ca.uhn.hl7v2.model.v251.datatype.DTM; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Util2 { + public static LocalDateTime parseLocalDateTime(DTM dtm) { + try { + return LocalDateTime.ofInstant(dtm.getValueAsDate().toInstant(), ZoneId.systemDefault()); + } catch (DataTypeException e) { + e.printStackTrace(); + } + return null; + } + + public static String parseIcd10Code(String icd10code) { + return removeWhitespaces(icd10code).substring(0, 5); + } + + public static String parseOpsCode(String opscode) { + return removeWhitespaces(opscode).substring(0, 7); + } + + private static String removeWhitespaces(String s) { + return s.replaceAll("\\s", ""); + } +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..393e087 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file From 981d8808d2aa997024fef45c7186b637f85c4ebd Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 00:15:37 +0100 Subject: [PATCH 03/14] HL7Server mittels HAPI implementiert und BAR_P05 Nachricht eingelesen. --- pom.xml | 12 +- .../mi/projmi6/hapi2/HL7ConnectionListener2.java | 20 +++ .../mi/projmi6/hapi2/HL7ExceptionHandler2.java | 16 +++ .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 150 +++++++++++++++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 62 +++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java | 33 +++++ src/main/resources/log4j.properties | 8 ++ 7 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java create mode 100644 src/main/resources/log4j.properties diff --git a/pom.xml b/pom.xml index b8b8785..0a4031c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 imi @@ -67,5 +67,15 @@ hapi-structures-v251 2.2 + + org.slf4j + slf4j-log4j12 + 1.6.6 + + + log4j + log4j + 1.2.17 + \ No newline at end of file diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java new file mode 100644 index 0000000..a0dbac6 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java @@ -0,0 +1,20 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.app.Connection; +import ca.uhn.hl7v2.app.ConnectionListener; + +/** + * Created by nils on 20.11.2015. + */ +class HL7ConnectionListener2 implements ConnectionListener { + + @Override + public void connectionReceived(Connection c) { + // System.out.println("New connection: " + c.getRemoteAddress().toString()); + } + + @Override + public void connectionDiscarded(Connection c) { + // System.out.println("Lost connection: " + c.getRemoteAddress().toString()); + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java new file mode 100644 index 0000000..b746016 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java @@ -0,0 +1,16 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; + +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7ExceptionHandler2 implements ReceivingApplicationExceptionHandler { + @Override + public String processException(String incomingMessage, Map incomingMetadata, String outgoingMessage, Exception e) throws HL7Exception { + return outgoingMessage; + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java new file mode 100644 index 0000000..0312971 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java @@ -0,0 +1,150 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.model.AbstractMessage; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import ca.uhn.hl7v2.model.v251.segment.*; +import ca.uhn.hl7v2.protocol.ReceivingApplication; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; +import de.uniluebeck.mi.projmi6.model.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Recever2 implements ReceivingApplication { + private final Class type; + + public HL7Recever2(Class type) { + this.type = type; + } + + + @Override + public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { + + if (type == ADT_A01.class) { + return processADT_A01(message, metadata); + } + if (type == BAR_P05.class) { + return processBAR_P05(message, metadata); + } + + // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + @Override + public boolean canProcess(Message message) { + // TODO: Erstmal alles processen. + return true; + } + + private Message generateACK(Message message) throws HL7Exception { + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { + Patient patient = new Patient(); + List faelle = new ArrayList<>(); + List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); + List ALLE_DIAGNOSEN = new ArrayList<>(); + + BAR_P05 bar_p05 = (BAR_P05) message; + + MSH msh = bar_p05.getMSH(); + PID pid = bar_p05.getPID(); + + patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); + + List visits = bar_p05.getVISITAll(); + + // Ab hier wird es dirty. + for (BAR_P05_VISIT visit : visits) { + + Fall fall = new Fall(); + fall.setPatient(patient); + + List diagnosen = new ArrayList<>(); + List untersuchungen = new ArrayList<>(); + + PV1 pv1 = visit.getPV1(); + // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) + Station station = new Station(); + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + StationsHistorie hist = new StationsHistorie(); + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); + fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); + + List dg1s = visit.getDG1All(); + for (DG1 dg1 : dg1s) { + Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. + // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! + String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... + int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... + Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); + + Diagnose diagnose = new Diagnose(); + diagnose.setIcd10code(icd10code); + diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) + diagnose.setFall(fall); + // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? + + diagnosen.add(diagnose); + } + List procedures = visit.getPROCEDUREAll(); + for (BAR_P05_PROCEDURE procedure : procedures) { + PR1 pr1 = procedure.getPR1(); + Untersuchung untersuchung = new Untersuchung(); + untersuchung.setFall(fall); + + OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... + untersuchung.setOpscode(opscode); + untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); + + String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. + int mitarbid = 1000; // TODO: Siehe oben + untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); + + // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) + + untersuchungen.add(untersuchung); + } + + // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... + faelle.add(fall); + ALLE_DIAGNOSEN.addAll(diagnosen); + ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); + } + + return generateACK(message); + } + + + private Message processADT_A01(Message message, Map metadata) throws HL7Exception { + ADT_A01 adt_a01 = (ADT_A01) message; + System.out.println(adt_a01.toString()); + + return generateACK(message); + } + +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java new file mode 100644 index 0000000..f302d4e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -0,0 +1,62 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.DefaultHapiContext; +import ca.uhn.hl7v2.HapiContext; +import ca.uhn.hl7v2.app.HL7Service; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Server2 { + + private static final int PORT = 1111; + private final HapiContext context; + private final HL7Service server; + private final ThreadPoolExecutor executor; + + public HL7Server2() throws InterruptedException { + executor = new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + context = new DefaultHapiContext(); + context.setExecutorService(executor); + server = context.newServer(PORT, false); + + server.registerApplication("ADT", "A01", new HL7Recever2(ADT_A01.class)); + server.registerApplication("BAR", "P05", new HL7Recever2(BAR_P05.class)); + + server.registerConnectionListener(new HL7ConnectionListener2()); + server.setExceptionHandler(new HL7ExceptionHandler2()); + + //server.startAndWait(); + server.start(); + } + + // TODO: Remove, for testing purpose only! + public static void main(String[] args) throws InterruptedException { + HL7Server2 srv = new HL7Server2(); + for (; ; ) { + + } + //srv.stop(); + //srv.shutdown(); + } + + public void stop() { + if (server != null && server.isRunning()) { + server.stop(); + } + } + + public void shutdown() { + if (executor != null && !executor.isTerminated()) { + executor.shutdown(); + } + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java new file mode 100644 index 0000000..b323e5e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java @@ -0,0 +1,33 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.model.DataTypeException; +import ca.uhn.hl7v2.model.v251.datatype.DTM; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Util2 { + public static LocalDateTime parseLocalDateTime(DTM dtm) { + try { + return LocalDateTime.ofInstant(dtm.getValueAsDate().toInstant(), ZoneId.systemDefault()); + } catch (DataTypeException e) { + e.printStackTrace(); + } + return null; + } + + public static String parseIcd10Code(String icd10code) { + return removeWhitespaces(icd10code).substring(0, 5); + } + + public static String parseOpsCode(String opscode) { + return removeWhitespaces(opscode).substring(0, 7); + } + + private static String removeWhitespaces(String s) { + return s.replaceAll("\\s", ""); + } +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..393e087 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file From 62addd42485d6cd9b1b90df2d7b80219526d5eaf Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 00:15:37 +0100 Subject: [PATCH 04/14] HL7Server mittels HAPI implementiert und BAR_P05 Nachricht eingelesen. --- pom.xml | 12 +- .../mi/projmi6/hapi2/HL7ConnectionListener2.java | 20 +++ .../mi/projmi6/hapi2/HL7ExceptionHandler2.java | 16 +++ .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 150 +++++++++++++++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 62 +++++++++ .../de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java | 33 +++++ src/main/resources/log4j.properties | 8 ++ 7 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java create mode 100644 src/main/resources/log4j.properties diff --git a/pom.xml b/pom.xml index b8b8785..0a4031c 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 imi @@ -67,5 +67,15 @@ hapi-structures-v251 2.2 + + org.slf4j + slf4j-log4j12 + 1.6.6 + + + log4j + log4j + 1.2.17 + \ No newline at end of file diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java new file mode 100644 index 0000000..a0dbac6 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java @@ -0,0 +1,20 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.app.Connection; +import ca.uhn.hl7v2.app.ConnectionListener; + +/** + * Created by nils on 20.11.2015. + */ +class HL7ConnectionListener2 implements ConnectionListener { + + @Override + public void connectionReceived(Connection c) { + // System.out.println("New connection: " + c.getRemoteAddress().toString()); + } + + @Override + public void connectionDiscarded(Connection c) { + // System.out.println("Lost connection: " + c.getRemoteAddress().toString()); + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java new file mode 100644 index 0000000..b746016 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java @@ -0,0 +1,16 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; + +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7ExceptionHandler2 implements ReceivingApplicationExceptionHandler { + @Override + public String processException(String incomingMessage, Map incomingMetadata, String outgoingMessage, Exception e) throws HL7Exception { + return outgoingMessage; + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java new file mode 100644 index 0000000..0312971 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java @@ -0,0 +1,150 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.model.AbstractMessage; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import ca.uhn.hl7v2.model.v251.segment.*; +import ca.uhn.hl7v2.protocol.ReceivingApplication; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; +import de.uniluebeck.mi.projmi6.model.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Recever2 implements ReceivingApplication { + private final Class type; + + public HL7Recever2(Class type) { + this.type = type; + } + + + @Override + public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { + + if (type == ADT_A01.class) { + return processADT_A01(message, metadata); + } + if (type == BAR_P05.class) { + return processBAR_P05(message, metadata); + } + + // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + @Override + public boolean canProcess(Message message) { + // TODO: Erstmal alles processen. + return true; + } + + private Message generateACK(Message message) throws HL7Exception { + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { + Patient patient = new Patient(); + List faelle = new ArrayList<>(); + List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); + List ALLE_DIAGNOSEN = new ArrayList<>(); + + BAR_P05 bar_p05 = (BAR_P05) message; + + MSH msh = bar_p05.getMSH(); + PID pid = bar_p05.getPID(); + + patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); + + List visits = bar_p05.getVISITAll(); + + // Ab hier wird es dirty. + for (BAR_P05_VISIT visit : visits) { + + Fall fall = new Fall(); + fall.setPatient(patient); + + List diagnosen = new ArrayList<>(); + List untersuchungen = new ArrayList<>(); + + PV1 pv1 = visit.getPV1(); + // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) + Station station = new Station(); + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + StationsHistorie hist = new StationsHistorie(); + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); + fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); + + List dg1s = visit.getDG1All(); + for (DG1 dg1 : dg1s) { + Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. + // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! + String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... + int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... + Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); + + Diagnose diagnose = new Diagnose(); + diagnose.setIcd10code(icd10code); + diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) + diagnose.setFall(fall); + // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? + + diagnosen.add(diagnose); + } + List procedures = visit.getPROCEDUREAll(); + for (BAR_P05_PROCEDURE procedure : procedures) { + PR1 pr1 = procedure.getPR1(); + Untersuchung untersuchung = new Untersuchung(); + untersuchung.setFall(fall); + + OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... + untersuchung.setOpscode(opscode); + untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); + + String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. + int mitarbid = 1000; // TODO: Siehe oben + untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); + + // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) + + untersuchungen.add(untersuchung); + } + + // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... + faelle.add(fall); + ALLE_DIAGNOSEN.addAll(diagnosen); + ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); + } + + return generateACK(message); + } + + + private Message processADT_A01(Message message, Map metadata) throws HL7Exception { + ADT_A01 adt_a01 = (ADT_A01) message; + System.out.println(adt_a01.toString()); + + return generateACK(message); + } + +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java new file mode 100644 index 0000000..f302d4e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -0,0 +1,62 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.DefaultHapiContext; +import ca.uhn.hl7v2.HapiContext; +import ca.uhn.hl7v2.app.HL7Service; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Server2 { + + private static final int PORT = 1111; + private final HapiContext context; + private final HL7Service server; + private final ThreadPoolExecutor executor; + + public HL7Server2() throws InterruptedException { + executor = new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + context = new DefaultHapiContext(); + context.setExecutorService(executor); + server = context.newServer(PORT, false); + + server.registerApplication("ADT", "A01", new HL7Recever2(ADT_A01.class)); + server.registerApplication("BAR", "P05", new HL7Recever2(BAR_P05.class)); + + server.registerConnectionListener(new HL7ConnectionListener2()); + server.setExceptionHandler(new HL7ExceptionHandler2()); + + //server.startAndWait(); + server.start(); + } + + // TODO: Remove, for testing purpose only! + public static void main(String[] args) throws InterruptedException { + HL7Server2 srv = new HL7Server2(); + for (; ; ) { + + } + //srv.stop(); + //srv.shutdown(); + } + + public void stop() { + if (server != null && server.isRunning()) { + server.stop(); + } + } + + public void shutdown() { + if (executor != null && !executor.isTerminated()) { + executor.shutdown(); + } + } +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java new file mode 100644 index 0000000..b323e5e --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java @@ -0,0 +1,33 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.model.DataTypeException; +import ca.uhn.hl7v2.model.v251.datatype.DTM; + +import java.time.LocalDateTime; +import java.time.ZoneId; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Util2 { + public static LocalDateTime parseLocalDateTime(DTM dtm) { + try { + return LocalDateTime.ofInstant(dtm.getValueAsDate().toInstant(), ZoneId.systemDefault()); + } catch (DataTypeException e) { + e.printStackTrace(); + } + return null; + } + + public static String parseIcd10Code(String icd10code) { + return removeWhitespaces(icd10code).substring(0, 5); + } + + public static String parseOpsCode(String opscode) { + return removeWhitespaces(opscode).substring(0, 7); + } + + private static String removeWhitespaces(String s) { + return s.replaceAll("\\s", ""); + } +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..393e087 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file From 80ee328c7a3b15e5fc29d808a41fbf0fcd7d3ff5 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 12:57:10 +0100 Subject: [PATCH 05/14] Fehlermeldungen angefanegn. --- src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java index 0312971..678e69d 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java @@ -1,5 +1,7 @@ package de.uniluebeck.mi.projmi6.hapi2; +import ca.uhn.hl7v2.AcknowledgmentCode; +import ca.uhn.hl7v2.ErrorCode; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.AbstractMessage; import ca.uhn.hl7v2.model.Message; @@ -60,6 +62,14 @@ public class HL7Recever2 implements ReceivingApplicat } } + private Message generateACKWithAR(Message message, String s) throws HL7Exception { + try { + return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.TABLE_VALUE_NOT_FOUND)); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { Patient patient = new Patient(); List faelle = new ArrayList<>(); From 2a030a18ea6bc908fff9ad7adc56eb5bcedd641a Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 15:27:54 +0100 Subject: [PATCH 06/14] Schreiben von empfangenen Dingen in die Datenbank. BAR_P05 --- src/main/java/de/uniluebeck/mi/projmi6/Main.java | 31 +-- .../de/uniluebeck/mi/projmi6/db/DBHandler.java | 13 ++ .../uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java | 245 +++++++++++++++++++++ .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 160 -------------- .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 9 +- 5 files changed, 279 insertions(+), 179 deletions(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java diff --git a/src/main/java/de/uniluebeck/mi/projmi6/Main.java b/src/main/java/de/uniluebeck/mi/projmi6/Main.java index 6d934bf..bf7c636 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/Main.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/Main.java @@ -2,9 +2,7 @@ package de.uniluebeck.mi.projmi6; import de.uniluebeck.mi.projmi6.controller.MainController; import de.uniluebeck.mi.projmi6.db.DBHandler; -import de.uniluebeck.mi.projmi6.model.Kasse; -import de.uniluebeck.mi.projmi6.model.Mitarbeiter; -import de.uniluebeck.mi.projmi6.model.OpsCode; +import de.uniluebeck.mi.projmi6.hapi2.HL7Server2; import javafx.application.Application; import javafx.beans.property.ReadOnlyStringProperty; import javafx.collections.FXCollections; @@ -14,7 +12,6 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Parent; import javafx.scene.Scene; -import javafx.scene.control.ProgressIndicator; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Background; @@ -72,6 +69,11 @@ public class Main extends Application { Parent root = fxmlLoader.load(); + // TODO: Jojo, das muss irgendwie am ende noch geschlossen werden! + HL7Server2 hl7server = new HL7Server2(mainController); + //hl7server.stop(); + //hl7server.shutdown(); + return root; } }; @@ -81,6 +83,14 @@ public class Main extends Application { */ private Image icon = new Image("icon.png", true); + /** + * Applications entry point. + * + * @param args Commandline parameters + */ + public static void main(String[] args) { + launch(args); + } @Override public void start(Stage primaryStage) { @@ -117,7 +127,7 @@ public class Main extends Application { * * @return the splash screen */ - public Stage createLoadWindow(ReadOnlyStringProperty progressMessage){ + public Stage createLoadWindow(ReadOnlyStringProperty progressMessage) { Text kis = new Text("KIS"); kis.setFont(Font.font(50)); @@ -127,7 +137,7 @@ public class Main extends Application { Text progress = new Text(); progress.textProperty().bind(progressMessage); - VBox root = new VBox(gruppe6, new ImageView(icon), kis, progress); + VBox root = new VBox(gruppe6, new ImageView(icon), kis, progress); root.setSpacing(20); root.setAlignment(Pos.CENTER); Scene scene = new Scene(root, 400, 500); @@ -140,13 +150,4 @@ public class Main extends Application { return stage; } - - /** - * Applications entry point. - * - * @param args Commandline parameters - */ - public static void main(String[] args) { - launch(args); - } } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java b/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java index 4982a1d..56c1e77 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java @@ -155,6 +155,7 @@ public class DBHandler { "`FallID`) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; private static final String DELETE_STATHIST = "DELETE FROM `stationshistorie` WHERE `StatHistID` =?"; + private static final String SELECT_FALLIDS_BY_PATID = "SELECT `fallid` FROM `fall` WHERE `patientid` =?"; private DBHandler() { @@ -841,4 +842,16 @@ public class DBHandler { entry.setSource(rs.getString("source")); return entry; } + + public static List getAlleFallIdsByPatID(int patid) throws SQLException { + PreparedStatement statement = MySqlConnectionFactory.getConnection().prepareStatement(SELECT_FALLIDS_BY_PATID); + statement.setInt(1, patid); + ResultSet rs = statement.executeQuery(); + + List fallids = new ArrayList<>(); + while (rs.next()) { + fallids.add(rs.getInt("fallid")); + } + return fallids; + } } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java new file mode 100644 index 0000000..b3d9f46 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java @@ -0,0 +1,245 @@ +package de.uniluebeck.mi.projmi6.hapi2; + +import ca.uhn.hl7v2.AcknowledgmentCode; +import ca.uhn.hl7v2.ErrorCode; +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.model.AbstractMessage; +import ca.uhn.hl7v2.model.Message; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; +import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; +import ca.uhn.hl7v2.model.v251.message.ADT_A01; +import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import ca.uhn.hl7v2.model.v251.segment.*; +import ca.uhn.hl7v2.protocol.ReceivingApplication; +import ca.uhn.hl7v2.protocol.ReceivingApplicationException; +import de.uniluebeck.mi.projmi6.controller.MainController; +import de.uniluebeck.mi.projmi6.db.DBHandler; +import de.uniluebeck.mi.projmi6.model.*; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Receiver2 implements ReceivingApplication { + private final Class type; + private final MainController mainctrl; + + public HL7Receiver2(Class type, MainController mainctrl) { + this.type = type; + this.mainctrl = mainctrl; + } + + + @Override + public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { + + if (type == ADT_A01.class) { + return processADT_A01(message, metadata); + } + if (type == BAR_P05.class) { + return processBAR_P05(message, metadata); + } + + // TODO: Handle unknown Messages, maybe write to database, send ACK and go on. + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + @Override + public boolean canProcess(Message message) { + // TODO: Erstmal alles processen. + return true; + } + + private Message generateACK(Message message) throws HL7Exception { + try { + return message.generateACK(); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message generateACKWithAR(Message message, String s) throws HL7Exception { + try { + return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.UNKNOWN_KEY_IDENTIFIER)); + } catch (IOException e) { + throw new HL7Exception(e); + } + } + + private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { + BAR_P05 bar_p05 = (BAR_P05) message; + + MSH msh = bar_p05.getMSH(); + PID pid = bar_p05.getPID(); + + int patid = Integer.parseInt(pid.getPatientID().encode()); + Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null); + + if (patient == null) { + return generateACKWithAR(message, "Patient nicht gefunden."); + } + + List visits = bar_p05.getVISITAll(); + + // Ab hier wird es dirty. + for (BAR_P05_VISIT visit : visits) { + PV1 pv1 = visit.getPV1(); + int fallid = Integer.parseInt(pv1.getVisitNumber().encode()); + + List fallids = new ArrayList<>(); + try { + fallids = DBHandler.getAlleFallIdsByPatID(patient.getPatID()); + } catch (SQLException e) { + e.printStackTrace(); + } + if (fallids.isEmpty() || !fallids.contains(fallid)) { + return generateACKWithAR(message, "Fall nicht gefunden."); + } + + Fall fall = new Fall(); + fall.setFallID(fallid); + fall.setPatient(patient); + + List diagnosen = new ArrayList<>(); + List untersuchungen = new ArrayList<>(); + + // Station(PV1-3-1), Fachabteilung(PV1-3-4), Aufnahmedatum(PV1-44), Entlassungsdatum(PV1-45), Fallnummer(PV1-19) + Station station = new Station(); + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + + StationsHistorie hist = new StationsHistorie(); + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); // TODO: null? + hist.setFallID(fallid); + + List dg1s = visit.getDG1All(); + for (DG1 dg1 : dg1s) { + Diagnose diagnose = new Diagnose(); + diagnose.setErsteller(99999); + diagnose.setBearbeiter(99999); + diagnose.setFall(fall); + + String icd10 = dg1.getDiagnosisCodeDG1().getIdentifier().encode(); + Icd10Code icd10code = mainctrl.getStammdaten().getIcd10Codes().stream().filter(i -> i.getCode().equals(icd10)).findFirst().orElse(null); + if (icd10code == null) { + // TODO: Oder einfach ueberspringen? + continue; + // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...) + // return generateACKWithAR(message, "ICD10 Code nicht gefunden."); + } + diagnose.setIcd10code(icd10code); + + // Mitarbeiter ID anhand von EinweisenderArzt erkennen. + Mitarbeiter mitarbeiter; + if (dg1.getDiagnosingClinician().length != 0) { + String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16) + mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); + if (mitarbeiter == null) { + return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); + } + } else { + mitarbeiter = new Mitarbeiter(99999); + } + diagnose.setArzt(mitarbeiter); + // (DG1-6) // TODO: Enum umstellen? Neeee... + String diagart = dg1.getDiagnosisType().encode(); + switch (diagart) { + case "A": + diagnose.setDiagArt(DiagArt.EINWEISUNG); + break; + case "F": + diagnose.setDiagArt(DiagArt.ENTLASSUNG); + break; + case "W": + default: + diagnose.setDiagArt(DiagArt.VERDACHT); + } + + diagnosen.add(diagnose); + } + List procedures = visit.getPROCEDUREAll(); + for (BAR_P05_PROCEDURE procedure : procedures) { + PR1 pr1 = procedure.getPR1(); + Untersuchung untersuchung = new Untersuchung(); + untersuchung.setErsteller(99999); + untersuchung.setBearbeiter(99999); + untersuchung.setFall(fall); + + String ops = pr1.getProcedureCode().encode(); + OpsCode opscode = mainctrl.getStammdaten().getOpsCodes().stream().filter(o -> o.getOpsCode().equals(ops)).findFirst().orElse(null); + if (opscode == null) { + // TODO: Oder einfach ueberspringen? + continue; + // TODO: Behandeln von sonder Codes. + // return generateACKWithAR(message, "OPS Code nicht gefunden."); + } + untersuchung.setOpscode(opscode); + + untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); + + // Mitarbeiter ID anhand von EinweisenderArzt erkennen. + Mitarbeiter mitarbeiter; + if (pr1.getProcedurePractitioner().length != 0) { + String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... + mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); + if (mitarbeiter == null) { + return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); + } + } else { + mitarbeiter = new Mitarbeiter(99999); + } + untersuchung.setDurchfuehrenderArzt(mitarbeiter); + + untersuchungen.add(untersuchung); + } + + // Hier jeweils Untersuchung und Diagnose in die Datenbank schreiben. + diagnosen.forEach(d -> { + try { + DBHandler.setDiagnose(d); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + + untersuchungen.forEach(u -> { + try { + DBHandler.setUntersuchung(u, 99999, false); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + } + + // HL7 Nachricht loggen. + try { + String sendind_ip = metadata.get("SENDING_IP").toString(); + String sendind_port = metadata.get("SENDING_PORT").toString(); + DBHandler.setHL7Nachricht(message.encode(), HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime()), sendind_ip + ":" + sendind_port); + } catch (SQLException e) { + e.printStackTrace(); + } + + return generateACK(message); + } + + + private Message processADT_A01(Message message, Map metadata) throws HL7Exception { + ADT_A01 adt_a01 = (ADT_A01) message; + System.out.println(adt_a01.toString()); + + return generateACK(message); + } + +} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java deleted file mode 100644 index 678e69d..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java +++ /dev/null @@ -1,160 +0,0 @@ -package de.uniluebeck.mi.projmi6.hapi2; - -import ca.uhn.hl7v2.AcknowledgmentCode; -import ca.uhn.hl7v2.ErrorCode; -import ca.uhn.hl7v2.HL7Exception; -import ca.uhn.hl7v2.model.AbstractMessage; -import ca.uhn.hl7v2.model.Message; -import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; -import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; -import ca.uhn.hl7v2.model.v251.message.ADT_A01; -import ca.uhn.hl7v2.model.v251.message.BAR_P05; -import ca.uhn.hl7v2.model.v251.segment.*; -import ca.uhn.hl7v2.protocol.ReceivingApplication; -import ca.uhn.hl7v2.protocol.ReceivingApplicationException; -import de.uniluebeck.mi.projmi6.model.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by nils on 20.11.2015. - */ -public class HL7Recever2 implements ReceivingApplication { - private final Class type; - - public HL7Recever2(Class type) { - this.type = type; - } - - - @Override - public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { - - if (type == ADT_A01.class) { - return processADT_A01(message, metadata); - } - if (type == BAR_P05.class) { - return processBAR_P05(message, metadata); - } - - // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. - try { - return message.generateACK(); - } catch (IOException e) { - throw new HL7Exception(e); - } - } - - @Override - public boolean canProcess(Message message) { - // TODO: Erstmal alles processen. - return true; - } - - private Message generateACK(Message message) throws HL7Exception { - try { - return message.generateACK(); - } catch (IOException e) { - throw new HL7Exception(e); - } - } - - private Message generateACKWithAR(Message message, String s) throws HL7Exception { - try { - return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.TABLE_VALUE_NOT_FOUND)); - } catch (IOException e) { - throw new HL7Exception(e); - } - } - - private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { - Patient patient = new Patient(); - List faelle = new ArrayList<>(); - List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); - List ALLE_DIAGNOSEN = new ArrayList<>(); - - BAR_P05 bar_p05 = (BAR_P05) message; - - MSH msh = bar_p05.getMSH(); - PID pid = bar_p05.getPID(); - - patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); - - List visits = bar_p05.getVISITAll(); - - // Ab hier wird es dirty. - for (BAR_P05_VISIT visit : visits) { - - Fall fall = new Fall(); - fall.setPatient(patient); - - List diagnosen = new ArrayList<>(); - List untersuchungen = new ArrayList<>(); - - PV1 pv1 = visit.getPV1(); - // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) - Station station = new Station(); - station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); - station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); - StationsHistorie hist = new StationsHistorie(); - hist.setStationKey(station.getStation()); - hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); - hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); - fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); - - List dg1s = visit.getDG1All(); - for (DG1 dg1 : dg1s) { - Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. - // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! - String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... - int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... - Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); - - Diagnose diagnose = new Diagnose(); - diagnose.setIcd10code(icd10code); - diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) - diagnose.setFall(fall); - // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? - - diagnosen.add(diagnose); - } - List procedures = visit.getPROCEDUREAll(); - for (BAR_P05_PROCEDURE procedure : procedures) { - PR1 pr1 = procedure.getPR1(); - Untersuchung untersuchung = new Untersuchung(); - untersuchung.setFall(fall); - - OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... - untersuchung.setOpscode(opscode); - untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); - - String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. - int mitarbid = 1000; // TODO: Siehe oben - untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); - - // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) - - untersuchungen.add(untersuchung); - } - - // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... - faelle.add(fall); - ALLE_DIAGNOSEN.addAll(diagnosen); - ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); - } - - return generateACK(message); - } - - - private Message processADT_A01(Message message, Map metadata) throws HL7Exception { - ADT_A01 adt_a01 = (ADT_A01) message; - System.out.println(adt_a01.toString()); - - return generateACK(message); - } - -} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java index f302d4e..a1f80d1 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -5,6 +5,7 @@ import ca.uhn.hl7v2.HapiContext; import ca.uhn.hl7v2.app.HL7Service; import ca.uhn.hl7v2.model.v251.message.ADT_A01; import ca.uhn.hl7v2.model.v251.message.BAR_P05; +import de.uniluebeck.mi.projmi6.controller.MainController; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -20,7 +21,7 @@ public class HL7Server2 { private final HL7Service server; private final ThreadPoolExecutor executor; - public HL7Server2() throws InterruptedException { + public HL7Server2(MainController mainctrl) throws InterruptedException { executor = new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); @@ -28,8 +29,8 @@ public class HL7Server2 { context.setExecutorService(executor); server = context.newServer(PORT, false); - server.registerApplication("ADT", "A01", new HL7Recever2(ADT_A01.class)); - server.registerApplication("BAR", "P05", new HL7Recever2(BAR_P05.class)); + server.registerApplication("ADT", "A01", new HL7Receiver2(ADT_A01.class, mainctrl)); + server.registerApplication("BAR", "P05", new HL7Receiver2(BAR_P05.class, mainctrl)); server.registerConnectionListener(new HL7ConnectionListener2()); server.setExceptionHandler(new HL7ExceptionHandler2()); @@ -40,7 +41,7 @@ public class HL7Server2 { // TODO: Remove, for testing purpose only! public static void main(String[] args) throws InterruptedException { - HL7Server2 srv = new HL7Server2(); + HL7Server2 srv = new HL7Server2(null); for (; ; ) { } From f3c0b1d93ceceec78a6a0fee4d52b662636c3af3 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 15:55:11 +0100 Subject: [PATCH 07/14] Loggen und aufrufen der GUI/Neue Nachricht. --- .../uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java | 34 +++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java index b3d9f46..d153e5a 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java @@ -18,6 +18,7 @@ import de.uniluebeck.mi.projmi6.model.*; import java.io.IOException; import java.sql.SQLException; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -85,11 +86,14 @@ public class HL7Receiver2 implements ReceivingApplica Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null); if (patient == null) { + logHL7MessageToDatabase(message, msh, metadata); return generateACKWithAR(message, "Patient nicht gefunden."); } List visits = bar_p05.getVISITAll(); + List updatedFallIDs = new ArrayList<>(); + // Ab hier wird es dirty. for (BAR_P05_VISIT visit : visits) { PV1 pv1 = visit.getPV1(); @@ -102,6 +106,7 @@ public class HL7Receiver2 implements ReceivingApplica e.printStackTrace(); } if (fallids.isEmpty() || !fallids.contains(fallid)) { + logHL7MessageToDatabase(message, msh, metadata); return generateACKWithAR(message, "Fall nicht gefunden."); } @@ -136,6 +141,7 @@ public class HL7Receiver2 implements ReceivingApplica // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...) + // logHL7MessageToDatabase(message, msh, metadata); // return generateACKWithAR(message, "ICD10 Code nicht gefunden."); } diagnose.setIcd10code(icd10code); @@ -146,6 +152,7 @@ public class HL7Receiver2 implements ReceivingApplica String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16) mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { + logHL7MessageToDatabase(message, msh, metadata); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { @@ -182,6 +189,7 @@ public class HL7Receiver2 implements ReceivingApplica // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. + // logHL7MessageToDatabase(message, msh, metadata); // return generateACKWithAR(message, "OPS Code nicht gefunden."); } untersuchung.setOpscode(opscode); @@ -194,6 +202,7 @@ public class HL7Receiver2 implements ReceivingApplica String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { + logHL7MessageToDatabase(message, msh, metadata); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { @@ -220,16 +229,15 @@ public class HL7Receiver2 implements ReceivingApplica e.printStackTrace(); } }); + + // Remember welche Faelle geaendert wurden + updatedFallIDs.add(fallid); } // HL7 Nachricht loggen. - try { - String sendind_ip = metadata.get("SENDING_IP").toString(); - String sendind_port = metadata.get("SENDING_PORT").toString(); - DBHandler.setHL7Nachricht(message.encode(), HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime()), sendind_ip + ":" + sendind_port); - } catch (SQLException e) { - e.printStackTrace(); - } + logHL7MessageToDatabase(message, msh, metadata); + // TODO: Runnable...??? Jojo??? + //updatedFallIDs.forEach(id -> mainctrl.getMessageController().addMessage(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); return generateACK(message); } @@ -242,4 +250,16 @@ public class HL7Receiver2 implements ReceivingApplica return generateACK(message); } + private void logHL7MessageToDatabase(Message message, MSH msh, Map metadata) throws HL7Exception { + try { + String sendind_ip = metadata.get("SENDING_IP").toString(); + String sendind_port = metadata.get("SENDING_PORT").toString(); + LocalDateTime ldt = HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime()); + DBHandler.setHL7Nachricht(message.encode(), ldt, sendind_ip + ":" + sendind_port); + } catch (SQLException e) { + e.printStackTrace(); + } + + } + } From 5b59a1194a9a08e3fad1a2ea50a098c448b86315 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 21:31:07 +0100 Subject: [PATCH 08/14] Weitere Anpassungen im parsen der BAR_P05 Nachrichten, schreiben in DB und Info an GUI. --- src/main/java/de/uniluebeck/mi/projmi6/Main.java | 17 ++- .../de/uniluebeck/mi/projmi6/db/DBHandler.java | 16 +++ .../uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java | 48 +++++-- .../uniluebeck/mi/projmi6/hapi2/HL7Recever2.java | 150 --------------------- .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 10 -- .../uniluebeck/mi/projmi6/model/HL7LogEntry.java | 71 ++++++++-- 6 files changed, 121 insertions(+), 191 deletions(-) delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java diff --git a/src/main/java/de/uniluebeck/mi/projmi6/Main.java b/src/main/java/de/uniluebeck/mi/projmi6/Main.java index bf7c636..55a55e4 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/Main.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/Main.java @@ -27,12 +27,15 @@ import javafx.stage.StageStyle; public class Main extends Application { + private HL7Server2 server; + /** * Cuz building the GUI from FXML is a bit costly, * it's done from its own thread. */ private Task loadMainWindowTask = new Task(){ + @Override protected Parent call() throws Exception { @@ -70,14 +73,11 @@ public class Main extends Application { Parent root = fxmlLoader.load(); // TODO: Jojo, das muss irgendwie am ende noch geschlossen werden! - HL7Server2 hl7server = new HL7Server2(mainController); - //hl7server.stop(); - //hl7server.shutdown(); + server = new HL7Server2(mainController); return root; } }; - /** * The applications logo (an owl). */ @@ -93,6 +93,15 @@ public class Main extends Application { } @Override + public void stop() throws Exception { + if (server != null) { + server.stop(); + server.shutdown(); + } + super.stop(); + } + + @Override public void start(Stage primaryStage) { System.out.println(getClass().getClassLoader().getResource("").toExternalForm()); diff --git a/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java b/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java index 56c1e77..532dfbd 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/db/DBHandler.java @@ -156,6 +156,12 @@ public class DBHandler { "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; private static final String DELETE_STATHIST = "DELETE FROM `stationshistorie` WHERE `StatHistID` =?"; private static final String SELECT_FALLIDS_BY_PATID = "SELECT `fallid` FROM `fall` WHERE `patientid` =?"; + private static final String INSERT_HL7NACHRICHT_ = "INSERT INTO `hl7_nachrichten` " + + "(`hl7msg`," + + "`timestamp`," + + "`source`," + + "`direction`) " + + "VALUES (?, ?, ?, ?)"; private DBHandler() { @@ -835,11 +841,21 @@ public class DBHandler { return hl7entries; } + public static void setHL7LogEntry(HL7LogEntry entry) throws SQLException { + PreparedStatement statement = MySqlConnectionFactory.getConnection().prepareStatement(INSERT_HL7NACHRICHT_); + statement.setString(1, entry.getMessage()); + statement.setTimestamp(2, Timestamp.valueOf(entry.getTimestamp())); + statement.setString(3, entry.getSource()); + statement.setString(4, entry.getDirection().toString()); + statement.execute(); + } + private static HL7LogEntry getHL7LogEntry(ResultSet rs) throws SQLException { HL7LogEntry entry = new HL7LogEntry(rs.getInt("msgid")); entry.setMessage(rs.getString("hl7msg")); entry.setTimestamp(rs.getTimestamp("timestamp").toLocalDateTime()); entry.setSource(rs.getString("source")); + entry.setDirection(HL7LogEntry.Direction.parseDirection(rs.getString("direction"))); return entry; } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java index d153e5a..58e7516 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java @@ -15,6 +15,7 @@ import ca.uhn.hl7v2.protocol.ReceivingApplicationException; import de.uniluebeck.mi.projmi6.controller.MainController; import de.uniluebeck.mi.projmi6.db.DBHandler; import de.uniluebeck.mi.projmi6.model.*; +import javafx.application.Platform; import java.io.IOException; import java.sql.SQLException; @@ -86,7 +87,8 @@ public class HL7Receiver2 implements ReceivingApplica Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null); if (patient == null) { - logHL7MessageToDatabase(message, msh, metadata); + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Patient nicht gefunden.", true)); return generateACKWithAR(message, "Patient nicht gefunden."); } @@ -106,7 +108,8 @@ public class HL7Receiver2 implements ReceivingApplica e.printStackTrace(); } if (fallids.isEmpty() || !fallids.contains(fallid)) { - logHL7MessageToDatabase(message, msh, metadata); + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true)); return generateACKWithAR(message, "Fall nicht gefunden."); } @@ -141,7 +144,8 @@ public class HL7Receiver2 implements ReceivingApplica // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...) - // logHL7MessageToDatabase(message, msh, metadata); + // logInHL7MessageToDatabase(message, msh, metadata); + // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "ICD10 Code nicht gefunden.", true)); // return generateACKWithAR(message, "ICD10 Code nicht gefunden."); } diagnose.setIcd10code(icd10code); @@ -152,7 +156,8 @@ public class HL7Receiver2 implements ReceivingApplica String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16) mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { - logHL7MessageToDatabase(message, msh, metadata); + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { @@ -189,7 +194,8 @@ public class HL7Receiver2 implements ReceivingApplica // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. - // logHL7MessageToDatabase(message, msh, metadata); + // logInHL7MessageToDatabase(message, msh, metadata); + // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "OPS Code nicht gefunden.", true)); // return generateACKWithAR(message, "OPS Code nicht gefunden."); } untersuchung.setOpscode(opscode); @@ -202,7 +208,8 @@ public class HL7Receiver2 implements ReceivingApplica String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { - logHL7MessageToDatabase(message, msh, metadata); + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { @@ -235,9 +242,9 @@ public class HL7Receiver2 implements ReceivingApplica } // HL7 Nachricht loggen. - logHL7MessageToDatabase(message, msh, metadata); + logInHL7MessageToDatabase(message, msh, metadata); // TODO: Runnable...??? Jojo??? - //updatedFallIDs.forEach(id -> mainctrl.getMessageController().addMessage(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); + updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); return generateACK(message); } @@ -250,16 +257,31 @@ public class HL7Receiver2 implements ReceivingApplica return generateACK(message); } - private void logHL7MessageToDatabase(Message message, MSH msh, Map metadata) throws HL7Exception { + private void logHL7MessageToDatabase(Message message, MSH msh, Map metadata, HL7LogEntry.Direction direction) throws HL7Exception { + String sendind_ip = metadata.get("SENDING_IP").toString(); + String sendind_port = metadata.get("SENDING_PORT").toString(); + LocalDateTime ldt = HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime()); + + HL7LogEntry entry = new HL7LogEntry(); + + entry.setMessage(message.encode()); + entry.setTimestamp(ldt); + entry.setSource(sendind_ip + ":" + sendind_port); + entry.setDirection(direction); + try { - String sendind_ip = metadata.get("SENDING_IP").toString(); - String sendind_port = metadata.get("SENDING_PORT").toString(); - LocalDateTime ldt = HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime()); - DBHandler.setHL7Nachricht(message.encode(), ldt, sendind_ip + ":" + sendind_port); + // DBHandler.setHL7Nachricht(message.encode(), ldt, sendind_ip + ":" + sendind_port); + DBHandler.setHL7LogEntry(entry); } catch (SQLException e) { e.printStackTrace(); } + } + private void logInHL7MessageToDatabase(Message message, MSH msh, Map metadata) throws HL7Exception { + logHL7MessageToDatabase(message, msh, metadata, HL7LogEntry.Direction.IN); } + private void updateUI(HL7Message hl7message) { + Platform.runLater(() -> mainctrl.getMessageController().addMessage(hl7message)); + } } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java deleted file mode 100644 index 0312971..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Recever2.java +++ /dev/null @@ -1,150 +0,0 @@ -package de.uniluebeck.mi.projmi6.hapi2; - -import ca.uhn.hl7v2.HL7Exception; -import ca.uhn.hl7v2.model.AbstractMessage; -import ca.uhn.hl7v2.model.Message; -import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; -import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; -import ca.uhn.hl7v2.model.v251.message.ADT_A01; -import ca.uhn.hl7v2.model.v251.message.BAR_P05; -import ca.uhn.hl7v2.model.v251.segment.*; -import ca.uhn.hl7v2.protocol.ReceivingApplication; -import ca.uhn.hl7v2.protocol.ReceivingApplicationException; -import de.uniluebeck.mi.projmi6.model.*; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by nils on 20.11.2015. - */ -public class HL7Recever2 implements ReceivingApplication { - private final Class type; - - public HL7Recever2(Class type) { - this.type = type; - } - - - @Override - public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { - - if (type == ADT_A01.class) { - return processADT_A01(message, metadata); - } - if (type == BAR_P05.class) { - return processBAR_P05(message, metadata); - } - - // TODO: Handle unknown Messages, maybe write to database, sen ACK and go on. - try { - return message.generateACK(); - } catch (IOException e) { - throw new HL7Exception(e); - } - } - - @Override - public boolean canProcess(Message message) { - // TODO: Erstmal alles processen. - return true; - } - - private Message generateACK(Message message) throws HL7Exception { - try { - return message.generateACK(); - } catch (IOException e) { - throw new HL7Exception(e); - } - } - - private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { - Patient patient = new Patient(); - List faelle = new ArrayList<>(); - List ALLE_UNTERSUCHUNGEN = new ArrayList<>(); - List ALLE_DIAGNOSEN = new ArrayList<>(); - - BAR_P05 bar_p05 = (BAR_P05) message; - - MSH msh = bar_p05.getMSH(); - PID pid = bar_p05.getPID(); - - patient.setPatID(Integer.parseInt(pid.getPatientID().encode())); - - List visits = bar_p05.getVISITAll(); - - // Ab hier wird es dirty. - for (BAR_P05_VISIT visit : visits) { - - Fall fall = new Fall(); - fall.setPatient(patient); - - List diagnosen = new ArrayList<>(); - List untersuchungen = new ArrayList<>(); - - PV1 pv1 = visit.getPV1(); - // TODO: Extract Station(PV1-3-1),Fachabteilung(PV1-3-4),Aufnahmedatum(PV1-44),Entlassungsdatum(PV1-45),Fallnummer(PV1-19) - Station station = new Station(); - station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); - station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); - StationsHistorie hist = new StationsHistorie(); - hist.setStationKey(station.getStation()); - hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); - hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); - fall.setFallID(Integer.parseInt(pv1.getVisitNumber().encode())); - - List dg1s = visit.getDG1All(); - for (DG1 dg1 : dg1s) { - Icd10Code icd10code = new Icd10Code(dg1.getDiagnosisCodeDG1().getIdentifier().encode(), "", 20); // TODO: Version hard gecoded. - // TODO: Mitarbeiter ID anhand von EinweisenderArzt erkennen! - String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // TODO: Wir holen uns immer den ersten der verantwortlichen Aerzte... - int mitarbid = 1000; // TODO: SQL: SELECT * FROM Mitarbeiter WHERE einweisenderarzt = ... - Mitarbeiter mitarbeiter = new Mitarbeiter(mitarbid); - - Diagnose diagnose = new Diagnose(); - diagnose.setIcd10code(icd10code); - diagnose.setArzt(mitarbeiter); // TODO: (DG1-16) - diagnose.setFall(fall); - // diagnose.setDiagArt(); // TODO: (DG1-6) // Enum umstellen???? - - diagnosen.add(diagnose); - } - List procedures = visit.getPROCEDUREAll(); - for (BAR_P05_PROCEDURE procedure : procedures) { - PR1 pr1 = procedure.getPR1(); - Untersuchung untersuchung = new Untersuchung(); - untersuchung.setFall(fall); - - OpsCode opscode = new OpsCode(pr1.getProcedureCode().encode(), "", 20); // TODO: Version hardcoded... - untersuchung.setOpscode(opscode); - untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); - - String einweisenderarzt = pr1.getPr112_ProcedurePractitioner(0).encode(); // TODO: Wieder nur den ersten Arzt.. - int mitarbid = 1000; // TODO: Siehe oben - untersuchung.setDurchfuehrenderArzt(new Mitarbeiter(mitarbid)); - - // TODO: Extract OPS(3), Zeitpunkt(5), Arzt(12) - - untersuchungen.add(untersuchung); - } - - // TODO: hier jeweils Fall, Untersuchung und Diagnosen in die Datenbank schreiben... - faelle.add(fall); - ALLE_DIAGNOSEN.addAll(diagnosen); - ALLE_UNTERSUCHUNGEN.addAll(untersuchungen); - } - - return generateACK(message); - } - - - private Message processADT_A01(Message message, Map metadata) throws HL7Exception { - ADT_A01 adt_a01 = (ADT_A01) message; - System.out.println(adt_a01.toString()); - - return generateACK(message); - } - -} diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java index a1f80d1..f670f6a 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java @@ -39,16 +39,6 @@ public class HL7Server2 { server.start(); } - // TODO: Remove, for testing purpose only! - public static void main(String[] args) throws InterruptedException { - HL7Server2 srv = new HL7Server2(null); - for (; ; ) { - - } - //srv.stop(); - //srv.shutdown(); - } - public void stop() { if (server != null && server.isRunning()) { server.stop(); diff --git a/src/main/java/de/uniluebeck/mi/projmi6/model/HL7LogEntry.java b/src/main/java/de/uniluebeck/mi/projmi6/model/HL7LogEntry.java index bcacbd0..8468bb9 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/model/HL7LogEntry.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/model/HL7LogEntry.java @@ -9,26 +9,44 @@ import java.time.LocalDateTime; * Created by 631806 on 19.11.15. */ public class HL7LogEntry { - private final int msgid; private final SimpleStringProperty message = new SimpleStringProperty(this, "message"); private final SimpleStringProperty source = new SimpleStringProperty(this, "source"); + private final SimpleObjectProperty direction = new SimpleObjectProperty<>(this, "direction"); + private final SimpleObjectProperty timestamp = new SimpleObjectProperty<>(this, "timestamp"); + private int msgid; + + public HL7LogEntry() { + + } public HL7LogEntry(int msgid) { this.msgid = msgid; } - public LocalDateTime getTimestamp() { - return timestamp.get(); + public Direction getDirection() { + return direction.get(); } - public SimpleObjectProperty timestampProperty() { - return timestamp; + public void setDirection(Direction direction) { + this.direction.set(direction); + } + + public SimpleObjectProperty directionProperty() { + return direction; + } + + public LocalDateTime getTimestamp() { + return timestamp.get(); } public void setTimestamp(LocalDateTime timestamp) { this.timestamp.set(timestamp); } + public SimpleObjectProperty timestampProperty() { + return timestamp; + } + public int getMsgid() { return msgid; } @@ -37,26 +55,51 @@ public class HL7LogEntry { return message.get(); } - public SimpleStringProperty messageProperty() { - return message; - } - public void setMessage(String message) { this.message.set(message); } - public String getSource() { - return source.get(); + public SimpleStringProperty messageProperty() { + return message; } - public SimpleStringProperty sourceProperty() { - return source; + public String getSource() { + return source.get(); } public void setSource(String source) { this.source.set(source); } + public SimpleStringProperty sourceProperty() { + return source; + } - private final SimpleObjectProperty timestamp = new SimpleObjectProperty<>(this, "timestamp"); + public enum Direction { + IN("in"), + OUT("out"), + UNKNOWN("o"); + + private final String direction; + + Direction(String direction) { + this.direction = direction; + } + + public static Direction parseDirection(String direction) { + switch (direction) { + case "in": + return IN; + case "out": + return OUT; + default: + return UNKNOWN; + } + } + + @Override + public String toString() { + return direction; + } + } } From 04da7b16ff24a2c01fb9a46bcc0c2c53c988a3a5 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sat, 21 Nov 2015 21:50:01 +0100 Subject: [PATCH 09/14] Nur noch bekannte MSG annehmen. --- src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java index 58e7516..07de57e 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java @@ -58,7 +58,7 @@ public class HL7Receiver2 implements ReceivingApplica @Override public boolean canProcess(Message message) { // TODO: Erstmal alles processen. - return true; + return message instanceof BAR_P05 || message instanceof ADT_A01; } private Message generateACK(Message message) throws HL7Exception { From 8700d87d6b8eecc0125356f84cd86364285853aa Mon Sep 17 00:00:00 2001 From: Johannes Date: Sat, 21 Nov 2015 22:59:29 +0100 Subject: [PATCH 10/14] =?UTF-8?q?Bugfix=20mit=20den=20LogTabellen;=20Bei?= =?UTF-8?q?=20einer=20empfangenen=20OP-Nachricht=20wird=20nun=20Patient=20?= =?UTF-8?q?+=20Diagnose=20ge=C3=B6ffnet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mi/projmi6/controller/LogController.java | 30 ++++++++++++++++--- .../mi/projmi6/controller/MainController.java | 35 ++++++++++++++++++++++ .../mi/projmi6/controller/MessageController.java | 4 +-- .../projmi6/controller/MessageListController.java | 4 ++- .../controller/PatientTablesController.java | 5 ++++ src/main/resources/log.fxml | 9 +++--- 6 files changed, 75 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/uniluebeck/mi/projmi6/controller/LogController.java b/src/main/java/de/uniluebeck/mi/projmi6/controller/LogController.java index fa8855d..91eaba4 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/controller/LogController.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/controller/LogController.java @@ -5,9 +5,7 @@ import de.uniluebeck.mi.projmi6.model.HL7LogEntry; import javafx.collections.FXCollections; import javafx.concurrent.Task; import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; +import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.text.Text; @@ -48,7 +46,30 @@ public class LogController { private void initColumns(){ colLogIp.setCellValueFactory(new PropertyValueFactory("source")); colLogTime.setCellValueFactory(new PropertyValueFactory("timestamp")); - colLogIp.setCellValueFactory(new PropertyValueFactory("message")); + colLogMessage.setCellValueFactory(new PropertyValueFactory("message")); + + colLogMessage.setCellFactory(column -> { + return new TableCell(){ + private TextArea textArea = new TextArea(); + { + textArea.setEditable(false); + textArea.setPrefRowCount(5); + } + + @Override + protected void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + this.setText(null); + if(item == null || empty){ + this.setGraphic(null); + return; + } + textArea.setText(item); + textArea.setWrapText(true); + this.setGraphic(textArea); + } + }; + }); } @@ -80,6 +101,7 @@ public class LogController { tblLog.setItems(FXCollections.observableArrayList(this.getValue())); mainController.decreaseParallelTaskCount(); btnRefresh.setDisable(false); + } @Override diff --git a/src/main/java/de/uniluebeck/mi/projmi6/controller/MainController.java b/src/main/java/de/uniluebeck/mi/projmi6/controller/MainController.java index b3f0b2e..4628da4 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/controller/MainController.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/controller/MainController.java @@ -152,6 +152,36 @@ public class MainController { } + private int fallIdToShow = -1; + + public void selectPatientAndFallId(Patient patient, int fallId){ + if(patientTablesController.getSelectedPatient()==patient + && !loadFallTask.isRunning()){ + selectFallById(fallId); + return; + } + + fallIdToShow = fallId; + patientTablesController.selectPatient(patient); + } + + private void selectFallById(int id){ + if(lvFall.getItems() == null){ + return; + } + + for(Fall fall: lvFall.getItems()){ + if(fall.getFallID()== id ){ + lvFall.getSelectionModel().select(fall); + return; + } + } + + + } + + + @FXML private Label lvFallPlaceholder; @@ -187,6 +217,11 @@ public class MainController { lvFallPlaceholder.setText("Keine F\u00e4lle vorhanden!"); lvFall.setItems(FXCollections.observableArrayList(getValue())); decreaseParallelTaskCount(); + + if(fallIdToShow!=-1){ + selectFallById(fallIdToShow); + fallIdToShow = -1; + } } @Override diff --git a/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageController.java b/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageController.java index d1d90d3..1ca1021 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageController.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageController.java @@ -38,12 +38,10 @@ public class MessageController { @FXML private void initialize(){ messageIcon.messageCountProperty().bind(messages.sizeProperty()); - messages.add(new HL7Message(null, 0, LocalDateTime.now(), null, true)); } @FXML private void onMessageIconClicked(){ - showMessageList(); } @@ -63,7 +61,7 @@ public class MessageController { Stage stage = new Stage(); - stage.setTitle(messages.size()+ " neue HL7-Nachrichten"); + stage.setTitle("Neue HL7-Nachrichten"); stage.setScene(new Scene(root, 600, 400)); stage.getIcons().add(new Image("icon.png")); diff --git a/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageListController.java b/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageListController.java index 98f9391..d67fa7f 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageListController.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/controller/MessageListController.java @@ -71,8 +71,10 @@ public class MessageListController { alert.initModality(Modality.APPLICATION_MODAL); alert.showAndWait(); + }else{ + mainController.selectPatientAndFallId(message.getPatient(), message.getFallId()); + ((Stage)lvMessages.getScene().getWindow()).close(); } - //TODO Go to patient } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/controller/PatientTablesController.java b/src/main/java/de/uniluebeck/mi/projmi6/controller/PatientTablesController.java index c0cef19..fbb9ea2 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/controller/PatientTablesController.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/controller/PatientTablesController.java @@ -223,6 +223,11 @@ public class PatientTablesController { stage.show(); } + public void selectPatient(Patient patient){ + patientOverviewTabPane.getSelectionModel().select(0); // Select first tab + tblPatientOverview.getSelectionModel().select(patient); + } + public void updatePatientsFromDb() { if (this.loadPatientTask != null && this.loadPatientTask.isRunning()) { System.out.println("Patienten werden bereits geladen."); diff --git a/src/main/resources/log.fxml b/src/main/resources/log.fxml index e0a1893..efd8cc5 100644 --- a/src/main/resources/log.fxml +++ b/src/main/resources/log.fxml @@ -1,23 +1,24 @@ + - + -