001 /** 002 * The contents of this file are subject to the Mozilla Public License Version 1.1 003 * (the "License"); you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 * Software distributed under the License is distributed on an "AS IS" basis, 006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 * specific language governing rights and limitations under the License. 008 * 009 * The Original Code is "SimpleServer.java". Description: 010 * "A simple TCP/IP-based HL7 server." 011 * 012 * The Initial Developer of the Original Code is University Health Network. Copyright (C) 013 * 2002. All Rights Reserved. 014 * 015 * Contributor(s): Kyle Buza 016 * 017 * Alternatively, the contents of this file may be used under the terms of the 018 * GNU General Public License (the ?GPL?), in which case the provisions of the GPL are 019 * applicable instead of those above. If you wish to allow use of your version of this 020 * file only under the terms of the GPL and not to allow others to use your version 021 * of this file under the MPL, indicate your decision by deleting the provisions above 022 * and replace them with the notice and other provisions required by the GPL License. 023 * If you do not delete the provisions above, a recipient may use your version of 024 * this file under either the MPL or the GPL. 025 */ 026 027 package ca.uhn.hl7v2.app; 028 029 import java.io.File; 030 import java.io.InterruptedIOException; 031 import java.net.ServerSocket; 032 import java.net.Socket; 033 034 import ca.uhn.hl7v2.llp.LowerLayerProtocol; 035 import ca.uhn.hl7v2.parser.Parser; 036 import ca.uhn.hl7v2.parser.PipeParser; 037 import ca.uhn.log.HapiLog; 038 import ca.uhn.log.HapiLogFactory; 039 040 /** 041 * <p>A simple TCP/IP-based HL7 server. This server listens for connections 042 * on a particular port, and creates a ConnectionManager for each incoming 043 * connection. </p> 044 * <p>A single SimpleServer can only service requests that use a 045 * single class of LowerLayerProtocol (specified at construction time).</p> 046 * <p>The ConnectionManager uses a PipeParser of the version specified in 047 * the constructor</p> 048 * <p>ConnectionManagers currently only support original mode processing.</p> 049 * <p>The ConnectionManager routes messages to various "Application"s based on 050 * message type. From the HL7 perspective, an Application is something that 051 * does something with a message.</p> 052 * @author Bryan Tripp 053 */ 054 public class SimpleServer extends HL7Service { 055 056 /** 057 * Socket timeout for simple server 058 */ 059 public static final int SO_TIMEOUT = 3000; 060 061 private static final HapiLog log = HapiLogFactory.getHapiLog(SimpleServer.class); 062 063 private int port; 064 065 /** 066 * Creates a new instance of SimpleServer that listens 067 * on the given port. Exceptions are logged using ca.uhn.hl7v2.Log; 068 */ 069 public SimpleServer(int port, LowerLayerProtocol llp, Parser parser) { 070 super(parser, llp); 071 this.port = port; 072 } 073 074 /** 075 * Loop that waits for a connection and starts a ConnectionManager 076 * when it gets one. 077 */ 078 public void run() { 079 try { 080 ServerSocket ss = new ServerSocket(port); 081 ss.setSoTimeout(SO_TIMEOUT); 082 log.info("SimpleServer running on port " + ss.getLocalPort()); 083 while (keepRunning()) { 084 try { 085 Socket newSocket = ss.accept(); 086 log.info("Accepted connection from " + newSocket.getInetAddress().getHostAddress()); 087 Connection conn = new Connection(parser, this.llp, newSocket); 088 newConnection(conn); 089 } 090 catch (InterruptedIOException ie) { 091 //ignore - just timed out waiting for connection 092 } 093 catch (Exception e) { 094 log.error( "Error while accepting connections: ", e); 095 } 096 } 097 098 ss.close(); 099 } 100 catch (Exception e) { 101 log.error(e); 102 } 103 finally { 104 //Bug 960113: Make sure HL7Service.stop() is called to stop ConnectionCleaner thread. 105 this.stop(); 106 } 107 } 108 109 /** 110 * Run server from command line. Port number should be passed as an argument, 111 * and a file containing a list of Applications to use can also be specified 112 * as an optional argument (as per <code>loadApplicationsFromFile(...)</code>). 113 * Uses the default LowerLayerProtocol. 114 */ 115 public static void main(String args[]) { 116 if (args.length < 1 || args.length > 2) { 117 System.out.println("Usage: ca.uhn.hl7v2.app.SimpleServer port_num [application_spec_file_name]"); 118 System.exit(1); 119 } 120 121 int port = 0; 122 try { 123 port = Integer.parseInt(args[0]); 124 } 125 catch (NumberFormatException e) { 126 System.err.println("The given port (" + args[0] + ") is not an integer."); 127 System.exit(1); 128 } 129 130 File appFile = null; 131 if (args.length == 2) { 132 appFile = new File(args[1]); 133 } 134 135 try { 136 SimpleServer server = new SimpleServer(port, LowerLayerProtocol.makeLLP(), new PipeParser()); 137 if (appFile != null) 138 server.loadApplicationsFromFile(appFile); 139 server.start(); 140 } 141 catch (Exception e) { 142 e.printStackTrace(); 143 } 144 145 } 146 147 }