From e8cc0ec9abb3175d93fa11109f14c61219335413 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Sun, 22 Nov 2015 12:19:55 +0100 Subject: [PATCH] Refactored names of HAPI/HL7 classes/package --- src/main/java/de/uniluebeck/mi/projmi6/Main.java | 6 +- .../mi/projmi6/hapi/HL7ConnectionListener.java | 20 ++ .../mi/projmi6/hapi/HL7ExceptionHandler.java | 16 ++ .../de/uniluebeck/mi/projmi6/hapi/HL7Receiver.java | 288 +++++++++++++++++++++ .../de/uniluebeck/mi/projmi6/hapi/HL7Server.java | 53 ++++ .../de/uniluebeck/mi/projmi6/hapi/HL7Util.java | 33 +++ .../mi/projmi6/hapi2/HL7ConnectionListener2.java | 20 -- .../mi/projmi6/hapi2/HL7ExceptionHandler2.java | 16 -- .../uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java | 288 --------------------- .../de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java | 53 ---- .../de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java | 33 --- 11 files changed, 413 insertions(+), 413 deletions(-) create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ConnectionListener.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ExceptionHandler.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Receiver.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Server.java create mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Util.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java delete mode 100644 src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java diff --git a/src/main/java/de/uniluebeck/mi/projmi6/Main.java b/src/main/java/de/uniluebeck/mi/projmi6/Main.java index 55a55e4..f358508 100644 --- a/src/main/java/de/uniluebeck/mi/projmi6/Main.java +++ b/src/main/java/de/uniluebeck/mi/projmi6/Main.java @@ -2,7 +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.hapi2.HL7Server2; +import de.uniluebeck.mi.projmi6.hapi.HL7Server; import javafx.application.Application; import javafx.beans.property.ReadOnlyStringProperty; import javafx.collections.FXCollections; @@ -27,7 +27,7 @@ import javafx.stage.StageStyle; public class Main extends Application { - private HL7Server2 server; + private HL7Server server; /** * Cuz building the GUI from FXML is a bit costly, @@ -73,7 +73,7 @@ public class Main extends Application { Parent root = fxmlLoader.load(); // TODO: Jojo, das muss irgendwie am ende noch geschlossen werden! - server = new HL7Server2(mainController); + server = new HL7Server(mainController); return root; } diff --git a/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ConnectionListener.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ConnectionListener.java new file mode 100644 index 0000000..cc972d6 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ConnectionListener.java @@ -0,0 +1,20 @@ +package de.uniluebeck.mi.projmi6.hapi; + +import ca.uhn.hl7v2.app.Connection; +import ca.uhn.hl7v2.app.ConnectionListener; + +/** + * Created by nils on 20.11.2015. + */ +class HL7ConnectionListener 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/hapi/HL7ExceptionHandler.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ExceptionHandler.java new file mode 100644 index 0000000..40f92ad --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7ExceptionHandler.java @@ -0,0 +1,16 @@ +package de.uniluebeck.mi.projmi6.hapi; + +import ca.uhn.hl7v2.HL7Exception; +import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; + +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7ExceptionHandler 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/hapi/HL7Receiver.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Receiver.java new file mode 100644 index 0000000..5ee5754 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Receiver.java @@ -0,0 +1,288 @@ +package de.uniluebeck.mi.projmi6.hapi; + +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 javafx.application.Platform; + +import java.io.IOException; +import java.sql.SQLException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Receiver implements ReceivingApplication { + private final Class type; + private final MainController mainctrl; + + public HL7Receiver(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 message instanceof BAR_P05 || message instanceof ADT_A01; + } + + 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) { + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(null, -1, LocalDateTime.now(), "Patient nicht gefunden.", true)); + return generateACKWithAR(message, "Patient nicht gefunden."); + } // TODO: Patienten und Fall neu anlegen??? Nicht verlangt! + + List visits = bar_p05.getVISITAll(); + + List updatedFallIDs = new ArrayList<>(); + + // 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)) { + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true)); + 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(); // TODO: Station holen! + station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); + station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); + + StationsHistorie hist = new StationsHistorie(); // TODO: StationsHist schreiben/schon vorhanden! + hist.setStationKey(station.getStation()); + hist.setAufnahmeDatum(HL7Util.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); + hist.setEntlassungsDatum(HL7Util.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...) + // 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); + + // 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) { + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); + 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); + } + diagnose.setFreiText(dg1.getDiagnosisDescription().encode()); + + 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. + // 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); + + untersuchung.setUntersuchungsdatum(HL7Util.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) { + logInHL7MessageToDatabase(message, msh, metadata); + updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); + 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(); + } + }); + + // Remember welche Faelle geaendert wurden + updatedFallIDs.add(fallid); + } + + // HL7 Nachricht loggen. + logInHL7MessageToDatabase(message, msh, metadata); + // TODO: Runnable...??? Jojo??? + updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); + + 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); + } + + 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 = HL7Util.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 { + // 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/hapi/HL7Server.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Server.java new file mode 100644 index 0000000..fff1919 --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Server.java @@ -0,0 +1,53 @@ +package de.uniluebeck.mi.projmi6.hapi; + +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 de.uniluebeck.mi.projmi6.controller.MainController; + +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Created by nils on 20.11.2015. + */ +public class HL7Server { + + private static final int PORT = 1111; + private final HapiContext context; + private final HL7Service server; + private final ThreadPoolExecutor executor; + + public HL7Server(MainController mainctrl) 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 HL7Receiver(ADT_A01.class, mainctrl)); + server.registerApplication("BAR", "P05", new HL7Receiver(BAR_P05.class, mainctrl)); + + server.registerConnectionListener(new HL7ConnectionListener()); + server.setExceptionHandler(new HL7ExceptionHandler()); + + //server.startAndWait(); + server.start(); + } + + 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/hapi/HL7Util.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Util.java new file mode 100644 index 0000000..84e4c3d --- /dev/null +++ b/src/main/java/de/uniluebeck/mi/projmi6/hapi/HL7Util.java @@ -0,0 +1,33 @@ +package de.uniluebeck.mi.projmi6.hapi; + +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 HL7Util { + 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/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java deleted file mode 100644 index a0dbac6..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ConnectionListener2.java +++ /dev/null @@ -1,20 +0,0 @@ -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 deleted file mode 100644 index b746016..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7ExceptionHandler2.java +++ /dev/null @@ -1,16 +0,0 @@ -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/HL7Receiver2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java deleted file mode 100644 index b529dd5..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Receiver2.java +++ /dev/null @@ -1,288 +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.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; -import java.time.LocalDateTime; -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 message instanceof BAR_P05 || message instanceof ADT_A01; - } - - 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) { - logInHL7MessageToDatabase(message, msh, metadata); - updateUI(new HL7Message(null, -1, LocalDateTime.now(), "Patient nicht gefunden.", true)); - return generateACKWithAR(message, "Patient nicht gefunden."); - } // TODO: Patienten und Fall neu anlegen??? Nicht verlangt! - - List visits = bar_p05.getVISITAll(); - - List updatedFallIDs = new ArrayList<>(); - - // 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)) { - logInHL7MessageToDatabase(message, msh, metadata); - updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true)); - 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(); // TODO: Station holen! - station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode()); - station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode()); - - StationsHistorie hist = new StationsHistorie(); // TODO: StationsHist schreiben/schon vorhanden! - 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...) - // 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); - - // 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) { - logInHL7MessageToDatabase(message, msh, metadata); - updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); - 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); - } - diagnose.setFreiText(dg1.getDiagnosisDescription().encode()); - - 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. - // 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); - - 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) { - logInHL7MessageToDatabase(message, msh, metadata); - updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); - 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(); - } - }); - - // Remember welche Faelle geaendert wurden - updatedFallIDs.add(fallid); - } - - // HL7 Nachricht loggen. - logInHL7MessageToDatabase(message, msh, metadata); - // TODO: Runnable...??? Jojo??? - updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); - - 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); - } - - 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 { - // 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/HL7Server2.java b/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java deleted file mode 100644 index f670f6a..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Server2.java +++ /dev/null @@ -1,53 +0,0 @@ -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 de.uniluebeck.mi.projmi6.controller.MainController; - -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(MainController mainctrl) 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 HL7Receiver2(ADT_A01.class, mainctrl)); - server.registerApplication("BAR", "P05", new HL7Receiver2(BAR_P05.class, mainctrl)); - - server.registerConnectionListener(new HL7ConnectionListener2()); - server.setExceptionHandler(new HL7ExceptionHandler2()); - - //server.startAndWait(); - server.start(); - } - - 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 deleted file mode 100644 index b323e5e..0000000 --- a/src/main/java/de/uniluebeck/mi/projmi6/hapi2/HL7Util2.java +++ /dev/null @@ -1,33 +0,0 @@ -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", ""); - } -}