1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package ca.uhn.hl7v2.protocol.impl;
28
29 import java.io.IOException;
30 import java.net.MalformedURLException;
31 import java.net.ServerSocket;
32 import java.net.URL;
33 import java.util.ArrayList;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.StringTokenizer;
37
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import ca.uhn.hl7v2.HL7Exception;
42 import ca.uhn.hl7v2.protocol.ApplicationRouter;
43 import ca.uhn.hl7v2.protocol.Processor;
44 import ca.uhn.hl7v2.protocol.ProcessorContext;
45 import ca.uhn.hl7v2.protocol.SafeStorage;
46 import ca.uhn.hl7v2.protocol.TransportException;
47 import ca.uhn.hl7v2.protocol.TransportLayer;
48
49
50
51
52
53
54
55 public class HL7Server {
56
57 private static final Logger log = LoggerFactory.getLogger(HL7Server.class);
58
59 private final ServerSocket myServerSocket;
60 private ServerSocket myServerSocket2;
61 private final ApplicationRouter myRouter;
62 private final SafeStorage myStorage;
63
64 private boolean myIsRunning = false;
65 private List<Processor> myProcessors;
66
67
68
69
70
71
72
73
74 public HL7Server(ServerSocket theServerSocket, ApplicationRouter theRouter, SafeStorage theStorage) {
75 myServerSocket = theServerSocket;
76 myRouter = theRouter;
77 myStorage = theStorage;
78 initProcessorList();
79 }
80
81
82
83
84
85
86
87
88
89
90 public HL7Server(ServerSocket theLocallyDriven, ServerSocket theRemotelyDriven,
91 ApplicationRouter theRouter, SafeStorage theStorage) {
92
93 myServerSocket = theLocallyDriven;
94 myServerSocket2 = theRemotelyDriven;
95 myRouter = theRouter;
96 myStorage = theStorage;
97 initProcessorList();
98 }
99
100
101 private void initProcessorList() {
102 myProcessors = new ArrayList<>();
103
104 final List<Processor> processors = myProcessors;
105 Thread cleaner = new Thread(() -> {
106 try {
107 Thread.sleep(1000);
108 } catch (InterruptedException ignored) {
109 }
110
111 synchronized (processors) {
112 Iterator<Processor> it = processors.iterator();
113 while (it.hasNext()) {
114 Processor proc = it.next();
115 if (!proc.getContext().getLocallyDrivenTransportLayer().isConnected()
116 || !proc.getContext().getRemotelyDrivenTransportLayer().isConnected()) {
117 it.remove();
118 }
119 }
120 }
121 });
122 cleaner.start();
123 }
124
125
126
127
128
129
130
131
132
133
134
135
136 public Processor accept(String theAddress) throws TransportException {
137 TransportLayer transport = getTransport(myServerSocket, theAddress);
138 ProcessorContext context;
139
140 if (myServerSocket2 == null) {
141 transport.connect();
142 context = new ProcessorContextImpl(myRouter, transport, myStorage);
143 } else {
144 TransportLayer transport2 = getTransport(myServerSocket2, theAddress);
145 DualTransportConnectorector.html#DualTransportConnector">DualTransportConnector connector = new DualTransportConnector(transport, transport2);
146 connector.connect();
147
148 context = new ProcessorContextImpl(myRouter, transport, transport2, myStorage);
149 }
150 return new ProcessorImpl(context, true);
151 }
152
153 private static TransportLayer getTransport(ServerSocket theServerSocket, String theAddress) throws TransportException {
154 ServerSocketStreamSourceStreamSource.html#ServerSocketStreamSource">ServerSocketStreamSource ss = new ServerSocketStreamSource(theServerSocket, theAddress);
155 return new MLLPTransport(ss);
156 }
157
158
159
160
161
162
163
164
165
166 public void start(final String theAddress) {
167 final HL7Server server = this;
168 Runnable acceptor = () -> {
169 while (server.isRunning()) {
170 try {
171 Processor p = server.accept(theAddress);
172 if (!myIsRunning) {
173 p.stop();
174 } else {
175 server.newProcessor(p);
176 Thread.sleep(1);
177 }
178 } catch (TransportException e) {
179 log.error(e.getMessage(), e);
180 } catch (InterruptedException ignored) {
181 }
182 }
183 };
184
185 myIsRunning = true;
186
187 Thread thd = new Thread(acceptor);
188 thd.start();
189 }
190
191 private synchronized void newProcessor(Processor theProcessor) {
192 myProcessors.add(theProcessor);
193 }
194
195
196
197
198 public synchronized void stop() {
199 myIsRunning = false;
200 for (Processor next : myProcessors) {
201 next.stop();
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214 public boolean isRunning() {
215 return myIsRunning;
216 }
217
218
219
220
221 public Processor[] getProcessors() {
222 return myProcessors.toArray(new Processor[0]);
223 }
224
225
226
227
228
229
230
231 private static URL getURL(String theUrlSpec) throws MalformedURLException {
232 URL url;
233 if (theUrlSpec.startsWith("classpath:")) {
234 StringTokenizer tok = new StringTokenizer(theUrlSpec, ":", false);
235 tok.nextToken();
236 String resource = tok.nextToken();
237 url = Thread.currentThread().getContextClassLoader().getResource(resource);
238 } else {
239 url = new URL(theUrlSpec);
240 }
241 return url;
242 }
243
244 public static void main(String[] args) {
245 if (args.length < 1 || args.length > 3) {
246 System.out.println("Usage: HL7Server (shared_port | (locally_driven_port remotely_driven_port)) app_binding_URL");
247 System.exit(1);
248 }
249
250 SafeStorage storage = new NullSafeStorage();
251 ApplicationRouter router = new ApplicationRouterImpl();
252
253 try {
254 HL7Server server;
255 String appURL;
256 if (args.length == 2) {
257 int port = Integer.parseInt(args[0]);
258 server = new HL7Server(new ServerSocket(port), router, storage);
259 appURL = args[1];
260 } else {
261 int localPort = Integer.parseInt(args[0]);
262 int remotePort = Integer.parseInt(args[1]);
263 server = new HL7Server(new ServerSocket(localPort), new ServerSocket(remotePort), router, storage);
264 appURL = args[2];
265 }
266
267 ApplicationLoader.loadApplications(router, getURL(appURL));
268
269 server.start(null);
270
271 } catch (NumberFormatException e) {
272 System.out.println("Port arguments must be integers");
273 System.exit(2);
274 } catch (IOException e) {
275 e.printStackTrace();
276 System.exit(3);
277 } catch (HL7Exception e) {
278 e.printStackTrace();
279 System.exit(4);
280 } catch (ClassNotFoundException e) {
281 e.printStackTrace();
282 System.exit(5);
283 } catch (InstantiationException e) {
284 e.printStackTrace();
285 System.exit(6);
286 } catch (IllegalAccessException e) {
287 e.printStackTrace();
288 System.exit(7);
289 }
290
291 }
292 }