| @@ -1,7 +1,10 @@ | |||
| package de.uniluebeck.mi.projmi6; | |||
| 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 de.uniluebeck.mi.projmi6.db.DBHandler; | |||
| import de.uniluebeck.mi.projmi6.hapi.HL7Receiver; | |||
| import de.uniluebeck.mi.projmi6.hapi.HL7Server; | |||
| import javafx.application.Application; | |||
| import javafx.beans.property.ReadOnlyStringProperty; | |||
| @@ -76,8 +79,10 @@ public class Main extends Application { | |||
| Parent root = fxmlLoader.load(); | |||
| // TODO: Jojo, das muss irgendwie am ende noch geschlossen werden! | |||
| server = new HL7Server(mainController); | |||
| server.registerApplication("ADT", "A01", new HL7Receiver<>(ADT_A01.class, mainController)); // ADT_A01 parsen | |||
| server.registerApplication("BAR", "P05", new HL7Receiver<>(BAR_P05.class, mainController)); // BAR_P05 parsen | |||
| server.start(); | |||
| return root; | |||
| } | |||
| @@ -124,6 +124,11 @@ public class HL7Receiver<T extends AbstractMessage> implements ReceivingApplicat | |||
| Station station = mainctrl.getStammdaten().getStationen().stream().filter(s -> s.getStation().equals(stat)).findFirst().orElse(null); | |||
| // TODO: Stationen mit falschen Abteilungen werden einfach umgeschrieben^^ | |||
| if (station == null) { | |||
| HL7Util.logInHL7MessageToDatabase(message, msh, metadata); | |||
| updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Station nicht gefunden.", true)); | |||
| return generateACKWithAR(message, "Station nicht gefunden."); | |||
| } | |||
| StationsHistorie hist = new StationsHistorie(); // TODO: StationsHist schreiben/schon vorhanden! | |||
| hist.setStationKey(station.getStation()); | |||
| hist.setAufnahmeDatum(HL7Util.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); | |||
| @@ -243,8 +248,7 @@ public class HL7Receiver<T extends AbstractMessage> implements ReceivingApplicat | |||
| // HL7 Nachricht loggen. | |||
| HL7Util.logInHL7MessageToDatabase(message, msh, metadata); | |||
| // TODO: Runnable...??? Jojo??? | |||
| updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false))); | |||
| updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "", false))); | |||
| return generateACK(message); | |||
| } | |||
| @@ -5,10 +5,7 @@ import ca.uhn.hl7v2.HL7Exception; | |||
| import ca.uhn.hl7v2.HapiContext; | |||
| import ca.uhn.hl7v2.model.Message; | |||
| import ca.uhn.hl7v2.model.v251.message.ADT_A01; | |||
| import ca.uhn.hl7v2.model.v251.segment.DG1; | |||
| import ca.uhn.hl7v2.model.v251.segment.EVN; | |||
| import ca.uhn.hl7v2.model.v251.segment.MSH; | |||
| import ca.uhn.hl7v2.model.v251.segment.PID; | |||
| import ca.uhn.hl7v2.model.v251.segment.*; | |||
| import ca.uhn.hl7v2.parser.Parser; | |||
| import ca.uhn.hl7v2.parser.PipeParser; | |||
| import ca.uhn.hl7v2.validation.ValidationContext; | |||
| @@ -56,35 +53,40 @@ public class HL7Sender { | |||
| //EVN Segment: | |||
| EVN evnSegment = adt.getEVN (); | |||
| evnSegment.getEvn1_EventTypeCode ().parse("A01"); | |||
| evnSegment.getEvn2_RecordedDateTime ().parse ( String.valueOf ( LocalDateTime.now () ) ); | |||
| evnSegment.getEvn4_EventReasonCode ().parse ( "01" ); | |||
| //Operator ID | |||
| //Event occured | |||
| //PID | |||
| PID pidSegment = adt.getPID (); | |||
| pidSegment.getPid3_PatientIdentifierList (0).getIDNumber ().setValue ( Integer.toString(patient.getPatID ()) ); | |||
| pidSegment.getPid5_PatientName (0).getFamilyName ().getSurname ().setValue ( patient.getNachname () ); | |||
| pidSegment.getPid5_PatientName (0).getGivenName ().setValue ( patient.getVorname () ); | |||
| pidSegment.getPid7_DateTimeOfBirth ().getTime ().setValue ( patient.getGeburtsdatum ().toString () ); | |||
| pidSegment.getPid8_AdministrativeSex ().setValue ( patient.getGeschlecht ().toString () ); | |||
| pidSegment.getPid11_PatientAddress (0).getStreetAddress ().getStreetName().setValue ( patient.getStrasse () ); | |||
| pidSegment.getPid11_PatientAddress (0).getStreetAddress ().getDwellingNumber ( ).setValue ( patient.getHausnummer () ); | |||
| pidSegment.getPid11_PatientAddress (0).getCity ().setValue (patient.getOrt () ); | |||
| pidSegment.getPid13_PhoneNumberHome (0).getTelephoneNumber ().setValue ( patient.getTelefon () ); | |||
| pidSegment.getPid16_MaritalStatus ().getAlternateIdentifier ().setValue ( patient.getFamilienstand ().toString()); | |||
| pidSegment.getPid2_PatientID ().getIDNumber ().parse ( String.valueOf ( patient.getPatID () ) ); | |||
| pidSegment.getPid3_PatientIdentifierList (0).getIDNumber ().parse ( Integer.toString(patient.getPatID ()) ); | |||
| pidSegment.getPid5_PatientName (0).getFamilyName ().getSurname ().parse ( patient.getNachname () ); | |||
| pidSegment.getPid5_PatientName (0).getGivenName ().parse ( patient.getVorname () ); | |||
| pidSegment.getPid7_DateTimeOfBirth ().getTime ().parse( patient.getGeburtsdatum ().toString () ); | |||
| pidSegment.getPid8_AdministrativeSex ().parse ( patient.getGeschlecht ().toString () ); | |||
| pidSegment.getPid11_PatientAddress (0).getStreetAddress ().getStreetName().parse ( patient.getStrasse () ); | |||
| pidSegment.getPid11_PatientAddress (0).getStreetAddress ().getDwellingNumber ( ).parse( patient.getHausnummer () ); | |||
| pidSegment.getPid11_PatientAddress (0).getCity ().parse (patient.getOrt () ); | |||
| pidSegment.getPid13_PhoneNumberHome (0).getTelephoneNumber ().parse ( patient.getTelefon () ); | |||
| pidSegment.getPid16_MaritalStatus ().getAlternateIdentifier ().parse ( patient.getFamilienstand ().toString()); | |||
| //Diagnosen | |||
| List<Diagnose> diagnosen = getDiagnosenByFall ( fall ); | |||
| diagnosen.add(fall.getHauptDiagnose ()); | |||
| PV1 pv1Segment = adt.getPV1 (); | |||
| pv1Segment.getPv12_PatientClass ().parse ( "U" ); | |||
| if(!diagnosen.isEmpty ()) { | |||
| int i =1; | |||
| for (Diagnose diagnose : diagnosen) { | |||
| DG1 dg1Segment = adt.getDG1 (); | |||
| dg1Segment.getDg11_SetIDDG1 ().parse ( String.valueOf ( i ) ); | |||
| dg1Segment.getDg13_DiagnosisCodeDG1 ().getIdentifier ().parse ( diagnose.getIcd10code ().getCode () ); | |||
| dg1Segment.getDg16_DiagnosisType ().setValue ( String.valueOf ( diagnose.getIcd10code ().getVersion () ) ); | |||
| dg1Segment.getDg116_DiagnosingClinician ()[0].parse ( diagnose.getArzt ().toString () ); | |||
| dg1Segment.getDg116_DiagnosingClinician ()[0].parse ( diagnose.getArzt ().getEinweisenderArzt () ); | |||
| dg1Segment.getDg14_DiagnosisDescription ().parse ( diagnose.getFreiText () ); | |||
| dg1Segment.getDg16_DiagnosisType ().parse ( diagnose.getDiagArt ().toString () ); | |||
| adt.getDG1All ().add ( dg1Segment ); | |||
| i++; | |||
| //Segment 2 Verschluesselung ? | |||
| } | |||
| } | |||
| @@ -3,8 +3,7 @@ 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 ca.uhn.hl7v2.protocol.ReceivingApplication; | |||
| import de.uniluebeck.mi.projmi6.controller.MainController; | |||
| import java.util.concurrent.ArrayBlockingQueue; | |||
| @@ -29,14 +28,18 @@ public class HL7Server { | |||
| context.setExecutorService(executor); | |||
| server = context.newServer(PORT, false); | |||
| server.registerApplication("ADT", "A01", new HL7Receiver<ADT_A01>(ADT_A01.class, mainctrl)); | |||
| server.registerApplication("BAR", "P05", new HL7Receiver<BAR_P05>(BAR_P05.class, mainctrl)); | |||
| server.registerConnectionListener(new HL7ConnectionListener()); | |||
| server.setExceptionHandler(new HL7ExceptionHandler()); | |||
| } | |||
| //server.startAndWait(); | |||
| server.start(); | |||
| public void registerApplication(String messageType, String triggerEvent, ReceivingApplication handler) { | |||
| server.registerApplication(messageType, triggerEvent, handler); | |||
| } | |||
| public void start() { | |||
| if (server != null) { | |||
| server.start(); | |||
| } | |||
| } | |||
| public void stop() { | |||
| @@ -0,0 +1,36 @@ | |||
| package de.uniluebeck.mi.projmi6.controller; | |||
| /** | |||
| * Created by 630030 on 19.11.15. | |||
| */ | |||
| import java.io.IOException; | |||
| import java.util.Map; | |||
| import ca.uhn.hl7v2.DefaultHapiContext; | |||
| import ca.uhn.hl7v2.HL7Exception; | |||
| import ca.uhn.hl7v2.model.Message; | |||
| import ca.uhn.hl7v2.protocol.ReceivingApplication; | |||
| import ca.uhn.hl7v2.protocol.ReceivingApplicationException; | |||
| /** | |||
| * Application class for receiving ADT^A01 messages | |||
| */ | |||
| public class OurReceiverApplication implements ReceivingApplication | |||
| { | |||
| /** | |||
| * {@inheritDoc} | |||
| */ | |||
| public boolean canProcess(Message theIn) { | |||
| return true; | |||
| } | |||
| /** | |||
| * {@inheritDoc} | |||
| */ | |||
| public Message processMessage(Message message, Map<String, Object> theMetadata) throws ReceivingApplicationException, HL7Exception { | |||
| String encodedMessage = new DefaultHapiContext().getPipeParser().encode(message); | |||
| System.out.println("Received message:\n" + encodedMessage + "\n\n"); | |||
| // Now generate a simple acknowledgment message and return it | |||
| try { | |||
| return message.generateACK(); | |||
| } catch (IOException e) { | |||
| throw new HL7Exception(e); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,231 @@ | |||
| package de.uniluebeck.mi.projmi6.hapi; | |||
| /** | |||
| * Created by 630030 on 19.11.15. | |||
| */ | |||
| import java.io.IOException; | |||
| import java.util.Map; | |||
| import ca.uhn.hl7v2.DefaultHapiContext; | |||
| import ca.uhn.hl7v2.HL7Exception; | |||
| import ca.uhn.hl7v2.HapiContext; | |||
| import ca.uhn.hl7v2.app.Connection; | |||
| import ca.uhn.hl7v2.app.ConnectionListener; | |||
| import ca.uhn.hl7v2.app.HL7Service; | |||
| import ca.uhn.hl7v2.app.Initiator; | |||
| import ca.uhn.hl7v2.llp.LLPException; | |||
| import ca.uhn.hl7v2.model.Message; | |||
| import ca.uhn.hl7v2.parser.Parser; | |||
| import ca.uhn.hl7v2.protocol.ReceivingApplication; | |||
| import ca.uhn.hl7v2.protocol.ReceivingApplicationExceptionHandler; | |||
| import de.uniluebeck.mi.projmi6.controller.OurReceiverApplication; | |||
| public class SendAndReceiveMessage { | |||
| public static void main(String[] args) throws Exception { | |||
| } | |||
| public void sendMessage(Message message){ | |||
| /* | |||
| * The following section of code establishes a server listening | |||
| * on port 1011 for new connections, and then "handles" them by | |||
| */ | |||
| int port = 1011; // The port to listen on | |||
| boolean useTls = false; // Don't use TLS/SSL | |||
| HapiContext context = new DefaultHapiContext(); | |||
| HL7Service server = context.newServer(port, useTls); | |||
| /* | |||
| * Create a client, which will connect to our waiting | |||
| * server and send messages to it. | |||
| */ | |||
| // A connection object represents a socket attached to an HL7 server | |||
| Connection connection = null; | |||
| try { | |||
| connection = context.newClient("localhost", port, useTls); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| // Create a message to send | |||
| String msg = "MSH|^~\\&|HIS|RIH|EKG|EKG|199904140038||ADT^A01|12345|P|2.2\r" | |||
| + "PID|0001|00009874|00001122|A00977|SMITH^JOHN^M|MOM|19581119|F|NOTREAL^LINDA^M|C|564 SPRING ST^^NEEDHAM^MA^02494^US|0002|(818)565-1551|(425)828-3344|E|S|C|0000444444|252-00-4414||||SA|||SA||||NONE|V1|0001|I|D.ER^50A^M110^01|ER|P00055|11B^M011^02|070615^BATMAN^GEORGE^L|555888^NOTREAL^BOB^K^DR^MD|777889^NOTREAL^SAM^T^DR^MD^PHD|ER|D.WT^1A^M010^01|||ER|AMB|02|070615^NOTREAL^BILL^L|ER|000001916994|D||||||||||||||||GDD|WA|NORM|02|O|02|E.IN^02D^M090^01|E.IN^01D^M080^01|199904072124|199904101200|199904101200||||5555112333|||666097^NOTREAL^MANNY^P\r" | |||
| + "NK1|0222555|NOTREAL^JAMES^R|FA|STREET^OTHER STREET^CITY^ST^55566|(222)111-3333|(888)999-0000|||||||ORGANIZATION\r" | |||
| + "PV1|0001|I|D.ER^1F^M950^01|ER|P000998|11B^M011^02|070615^BATMAN^GEORGE^L|555888^OKNEL^BOB^K^DR^MD|777889^NOTREAL^SAM^T^DR^MD^PHD|ER|D.WT^1A^M010^01|||ER|AMB|02|070615^VOICE^BILL^L|ER|000001916994|D||||||||||||||||GDD|WA|NORM|02|O|02|E.IN^02D^M090^01|E.IN^01D^M080^01|199904072124|199904101200|||||5555112333|||666097^DNOTREAL^MANNY^P\r" | |||
| + "PV2|||0112^TESTING|55555^PATIENT IS NORMAL|NONE|||19990225|19990226|1|1|TESTING|555888^NOTREAL^BOB^K^DR^MD||||||||||PROD^003^099|02|ER||NONE|19990225|19990223|19990316|NONE\r" | |||
| + "AL1||SEV|001^POLLEN\r" | |||
| + "GT1||0222PL|NOTREAL^BOB^B||STREET^OTHER STREET^CITY^ST^77787|(444)999-3333|(222)777-5555||||MO|111-33-5555||||NOTREAL GILL N|STREET^OTHER STREET^CITY^ST^99999|(111)222-3333\r" | |||
| + "IN1||022254P|4558PD|BLUE CROSS|STREET^OTHER STREET^CITY^ST^00990||(333)333-6666||221K|LENIX|||19980515|19990515|||PATIENT01 TEST D||||||||||||||||||02LL|022LP554"; | |||
| Parser p = context.getPipeParser(); | |||
| Message adt = null; | |||
| try { | |||
| adt = p.parse(msg); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| // The initiator is used to transmit unsolicited messages | |||
| Initiator initiator = connection.getInitiator(); | |||
| Message response = null; | |||
| try { | |||
| response = initiator.sendAndReceive(adt); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } catch (LLPException e) { | |||
| e.printStackTrace(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| String responseString = null; | |||
| try { | |||
| responseString = p.encode(response); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| System.out.println("Received response:\n" + responseString); | |||
| /* | |||
| * MSH|^~\&|||||20070218200627.515-0500||ACK|54|P|2.2 MSA|AA|12345 | |||
| */ | |||
| /* | |||
| * If you want to send another message to the same destination, it's fine | |||
| * to ask the context again for a client to attach to the same host/port. | |||
| * The context will be smart about it and return the same (already | |||
| * connected) client Connection instance, assuming it hasn't been closed. | |||
| */ | |||
| try { | |||
| connection = context.newClient("localhost", port, useTls); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| initiator = connection.getInitiator(); | |||
| try { | |||
| response = initiator.sendAndReceive(adt); | |||
| } catch (HL7Exception e) { | |||
| e.printStackTrace(); | |||
| } catch (LLPException e) { | |||
| e.printStackTrace(); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| /* | |||
| * Close the connection when you are done with it. | |||
| */ | |||
| connection.close(); | |||
| // Stop the receiving server and client | |||
| server.stopAndWait(); | |||
| } | |||
| public void receiveMessage(Message message){ | |||
| /* | |||
| * The following section of code establishes a server listening | |||
| * on port 1011 for new connections, and then "handles" them by | |||
| */ | |||
| int port = 1011; // The port to listen on | |||
| boolean useTls = false; // Don't use TLS/SSL | |||
| HapiContext context = new DefaultHapiContext(); | |||
| HL7Service server = context.newServer(port, useTls); | |||
| /* | |||
| * The server may have any number of "application" objects registered to | |||
| * handle messages. We are going to create an application to listen to | |||
| * BAR^P05 messages. | |||
| */ | |||
| ReceivingApplication handler = new OurReceiverApplication (); | |||
| server.registerApplication("BAR", "P05", handler); | |||
| /* | |||
| *We want to be notified any time a new connection comes in or is | |||
| * lost, so we register a connection listener | |||
| */ | |||
| server.registerConnectionListener(new MyConnectionListener()); | |||
| /* | |||
| * We want to be notified any processing failures when receiving, | |||
| * processing, or responding to messages with the server, so we | |||
| * register an exception handler. */ | |||
| server.setExceptionHandler(new MyExceptionHandler()); | |||
| // Start the server listening for messages | |||
| try { | |||
| server.startAndWait(); | |||
| } catch (InterruptedException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * Connection listener which is notified whenever a new | |||
| * connection comes in or is lost | |||
| */ | |||
| public static class MyConnectionListener implements ConnectionListener { | |||
| public void connectionReceived(Connection theC) { | |||
| System.out.println("New connection received: " + theC.getRemoteAddress().toString()); | |||
| } | |||
| public void connectionDiscarded(Connection theC) { | |||
| System.out.println("Lost connection from: " + theC.getRemoteAddress().toString()); | |||
| } | |||
| } | |||
| /** | |||
| * Exception handler which is notified any time | |||
| */ | |||
| public static class MyExceptionHandler implements ReceivingApplicationExceptionHandler { | |||
| /** | |||
| * Process an exception. | |||
| * | |||
| * @param theIncomingMessage | |||
| * the incoming message. This is the raw message which was | |||
| * received from the external system | |||
| * @param theIncomingMetadata | |||
| * Any metadata that accompanies the incoming message. See {@link ca.uhn.hl7v2.protocol.Transportable#getMetadata()} | |||
| * @param theOutgoingMessage | |||
| * the outgoing message. The response NAK message generated by | |||
| * HAPI. | |||
| * @param theE | |||
| * the exception which was received | |||
| * @return The new outgoing message. This can be set to the value provided | |||
| * by HAPI in <code>outgoingMessage</code>, or may be replaced with | |||
| * another message. <b>This method may not return <code>null</code></b>. | |||
| */ | |||
| public String processException(String theIncomingMessage, Map<String, Object> theIncomingMetadata, String theOutgoingMessage, Exception theE) throws HL7Exception { | |||
| /* | |||
| * Here you can do any processing you like. If you want to change | |||
| * the response (NAK) message which will be returned you may do | |||
| * so, or just return the NAK which HAPI already created (theOutgoingMessage) | |||
| */ | |||
| return theOutgoingMessage; | |||
| } | |||
| } | |||
| } | |||