Coverage Report - ca.uhn.hl7v2.app.Receiver
 
Classes in this File Line Coverage Branch Coverage Complexity
Receiver
78%
22/28
83%
5/6
2.4
Receiver$Grunt
100%
10/10
N/A
2.4
 
 1  
 /**
 2  
  * The contents of this file are subject to the Mozilla Public License Version 1.1
 3  
  * (the "License"); you may not use this file except in compliance with the License.
 4  
  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 5  
  * Software distributed under the License is distributed on an "AS IS" basis,
 6  
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
 7  
  * specific language governing rights and limitations under the License.
 8  
  *
 9  
  * The Original Code is "Receiver.java".  Description:
 10  
  * "Listens for incoming messages on a certain input stream, and
 11  
  * sends them to the appropriate location."
 12  
  *
 13  
  * The Initial Developer of the Original Code is University Health Network. Copyright (C)
 14  
  * 2002.  All Rights Reserved.
 15  
  *
 16  
  * Contributor(s): _____________.
 17  
  *
 18  
  * Alternatively, the contents of this file may be used under the terms of the
 19  
  * GNU General Public License (the "GPL"), in which case the provisions of the GPL are
 20  
  * applicable instead of those above.  If you wish to allow use of your version of this
 21  
  * file only under the terms of the GPL and not to allow others to use your version
 22  
  * of this file under the MPL, indicate your decision by deleting  the provisions above
 23  
  * and replace  them with the notice and other provisions required by the GPL License.
 24  
  * If you do not delete the provisions above, a recipient may use your version of
 25  
  * this file under either the MPL or the GPL.
 26  
  */
 27  
 
 28  
 package ca.uhn.hl7v2.app;
 29  
 
 30  
 import java.io.IOException;
 31  
 import java.net.SocketException;
 32  
 
 33  
 import org.slf4j.Logger;
 34  
 import org.slf4j.LoggerFactory;
 35  
 
 36  
 import ca.uhn.hl7v2.concurrent.Service;
 37  
 import ca.uhn.hl7v2.llp.HL7Reader;
 38  
 
 39  
 /**
 40  
  * Listens for incoming messages on a certain input stream, and sends them to
 41  
  * the appropriate location.
 42  
  * 
 43  
  * @author Bryan Tripp
 44  
  */
 45  1
 public class Receiver extends Service {
 46  
 
 47  1
         private static final Logger log = LoggerFactory.getLogger(Receiver.class);
 48  
 
 49  
         private Connection conn;
 50  
         private HL7Reader in;
 51  
 
 52  
         /** Creates a new instance of Receiver, associated with the given Connection */
 53  
         public Receiver(Connection c, HL7Reader in) {
 54  92
                 super("Receiver", c.getExecutorService());
 55  92
                 this.conn = c;
 56  92
                 this.in = in;
 57  92
         }
 58  
 
 59  
 
 60  
         @Override
 61  
         protected void handle() {
 62  
                 try {
 63  332
                         String message = in.getMessage();
 64  247
                         if (message == null) {
 65  20
                                 log.debug("Failed to read a message");
 66  
                         } else {
 67  227
                                 processMessage(message);
 68  
                         }
 69  85
                 } catch (SocketException e)  {
 70  
                         // This probably means that the client closed the server connection normally
 71  85
                         conn.close();
 72  85
                         log.info("SocketException: closing Connection, will no longer read messages with this Receiver: " + e.getMessage());
 73  0
                 } catch (IOException e) {
 74  0
                         conn.close();
 75  0
                         log.warn("IOException: closing Connection, will no longer read messages with this Receiver. ", e);
 76  0
                 } catch (Exception e) {
 77  0
                         log.error("Error while closing connection: ", e);
 78  332
                 }
 79  
 
 80  332
         }
 81  
 
 82  
 
 83  
         /**
 84  
          * Processes a single incoming message by sending it to the appropriate
 85  
          * internal location. If an incoming message contains an MSA-2 field, it is
 86  
          * assumed that this message is meant as a reply to a message that has been
 87  
          * sent earlier. In this case an attempt is give the message to the object
 88  
          * that sent the corresponding outbound message. If the message contains an
 89  
          * MSA-2 but there are no objects that appear to be waiting for it, it is
 90  
          * discarded and an exception is logged. If the message does not contain an
 91  
          * MSA-2 field, it is concluded that the message has arrived unsolicited. In
 92  
          * this case it is sent to the Responder (in a new Thread).
 93  
          */
 94  
         protected void processMessage(String message) {
 95  227
                 String ackID = conn.getParser().getAckID(message);
 96  227
                 if (ackID == null) {
 97  117
                         log.debug("Unsolicited Message Received: {}", message);
 98  117
                         getExecutorService().submit(new Grunt(conn, message));
 99  
                 } else {
 100  110
                         if (!conn.isRecipientWaiting(ackID, message)) {
 101  0
                                 log.info("Unexpected Message Received. This message appears to be an acknowledgement (MSA-2 has a value) so it will be ignored: {}", message);
 102  
                         } else {
 103  110
                                 log.debug("Response Message Received: {}", message);
 104  
                         }
 105  
                 }
 106  227
         }
 107  
 
 108  
         /** Independent thread for processing a single message */
 109  
         private class Grunt implements Runnable {
 110  
 
 111  
                 private Connection conn;
 112  
                 private String m;
 113  
 
 114  117
                 public Grunt(Connection conn, String message) {
 115  117
                         this.conn = conn;
 116  117
                         this.m = message;
 117  117
                 }
 118  
 
 119  
                 public void run() {
 120  
                         try {
 121  117
                                 String response = conn.getResponder().processMessage(m);
 122  116
                                 conn.getAckWriter().writeMessage(response);
 123  1
                         } catch (Exception e) {
 124  1
                                 log.error("Error while processing message: ", e);
 125  116
                         }
 126  117
                 }
 127  
         }
 128  
 
 129  
 }