Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
Receiver |
|
| 2.3333333333333335;2.333 | ||||
Receiver$Grunt |
|
| 2.3333333333333335;2.333 |
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 | 10 | public class Receiver extends Service { |
46 | ||
47 | 5 | private static final Logger log = LoggerFactory.getLogger(Receiver.class); |
48 | ||
49 | private ActiveConnection conn; | |
50 | private HL7Reader in; | |
51 | ||
52 | /** Creates a new instance of Receiver, associated with the given Connection */ | |
53 | public Receiver(ActiveConnection c, HL7Reader in) { | |
54 | 543 | super("Receiver", c.getExecutorService()); |
55 | 543 | this.conn = c; |
56 | 543 | this.in = in; |
57 | 543 | } |
58 | ||
59 | ||
60 | @Override | |
61 | protected void handle() { | |
62 | try { | |
63 | 1859 | String message = in.getMessage(); |
64 | 1345 | if (message == null) { |
65 | 134 | log.debug("Failed to read a message"); |
66 | } else { | |
67 | 1211 | processMessage(message); |
68 | } | |
69 | 499 | } catch (SocketException e) { |
70 | // This probably means that the client closed the server connection normally | |
71 | 499 | conn.close(); |
72 | 499 | log.info("SocketException: closing Connection from " + describeRemoteConnection() + ", 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 from " + describeRemoteConnection() + ", will no longer read messages with this Receiver. ", e); |
76 | 10 | } catch (Exception e) { |
77 | 10 | conn.close(); |
78 | 10 | log.error("Unexpected error, closing connection from " + describeRemoteConnection() + " - ", e); |
79 | 1844 | } |
80 | ||
81 | 1854 | } |
82 | ||
83 | ||
84 | private String describeRemoteConnection() { | |
85 | 509 | return conn.getRemoteAddress().getHostAddress() + ":" + conn.getRemotePort(); |
86 | } | |
87 | ||
88 | ||
89 | /** | |
90 | * Processes a single incoming message by sending it to the appropriate | |
91 | * internal location. If an incoming message contains an MSA-2 field, it is | |
92 | * assumed that this message is meant as a reply to a message that has been | |
93 | * sent earlier. In this case an attempt is give the message to the object | |
94 | * that sent the corresponding outbound message. If the message contains an | |
95 | * MSA-2 but there are no objects that appear to be waiting for it, it is | |
96 | * discarded and an exception is logged. If the message does not contain an | |
97 | * MSA-2 field, it is concluded that the message has arrived unsolicited. In | |
98 | * this case it is sent to the Responder (in a new Thread). | |
99 | */ | |
100 | protected void processMessage(String message) { | |
101 | 1211 | String ackID = conn.getParser().getAckID(message); |
102 | 1211 | if (ackID == null) { |
103 | 633 | log.debug("Unsolicited Message Received: {}", message); |
104 | 633 | getExecutorService().submit(new Grunt(conn, message)); |
105 | } else { | |
106 | 578 | if (!conn.isRecipientWaiting(ackID, message)) { |
107 | 0 | log.info("Unexpected Message Received. This message appears to be an acknowledgement (MSA-2 has a value) so it will be ignored: {}", message); |
108 | } else { | |
109 | 578 | log.debug("Response Message Received: {}", message); |
110 | } | |
111 | } | |
112 | 1211 | } |
113 | ||
114 | /** Independent thread for processing a single message */ | |
115 | private static class Grunt implements Runnable { | |
116 | ||
117 | private ActiveConnection conn; | |
118 | private String m; | |
119 | ||
120 | 633 | public Grunt(ActiveConnection conn, String message) { |
121 | 633 | this.conn = conn; |
122 | 633 | this.m = message; |
123 | 633 | } |
124 | ||
125 | public void run() { | |
126 | try { | |
127 | 633 | String response = conn.getResponder().processMessage(m); |
128 | 633 | if (response != null) { |
129 | 623 | conn.getAckWriter().writeMessage(response); |
130 | } else { | |
131 | 10 | log.debug("Not responding to incoming message"); |
132 | } | |
133 | 0 | } catch (Exception e) { |
134 | 0 | log.error("Error while processing message: ", e); |
135 | 633 | } |
136 | 633 | } |
137 | } | |
138 | ||
139 | } |