All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.uhn.hl7v2.app.SimpleServer Maven / Gradle / Ivy

There is a newer version: 2.5.1
Show newest version
/**
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
 * specific language governing rights and limitations under the License.
 *
 * The Original Code is "SimpleServer.java".  Description:
 * "A simple TCP/IP-based HL7 server."
 *
 * The Initial Developer of the Original Code is University Health Network. Copyright (C)
 * 2002.  All Rights Reserved.
 *
 * Contributor(s): Kyle Buza
 *
 * Alternatively, the contents of this file may be used under the terms of the
 * GNU General Public License (the  �GPL�), in which case the provisions of the GPL are
 * applicable instead of those above.  If you wish to allow use of your version of this
 * file only under the terms of the GPL and not to allow others to use your version
 * of this file under the MPL, indicate your decision by deleting  the provisions above
 * and replace  them with the notice and other provisions required by the GPL License.
 * If you do not delete the provisions above, a recipient may use your version of
 * this file under either the MPL or the GPL.
 */

package ca.uhn.hl7v2.app;

import java.io.File;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.app.AcceptorThread.AcceptedSocket;
import ca.uhn.hl7v2.concurrent.DefaultExecutorService;
import ca.uhn.hl7v2.llp.LowerLayerProtocol;
import ca.uhn.hl7v2.llp.MinLowerLayerProtocol;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.parser.PipeParser;
import ca.uhn.hl7v2.util.SocketFactory;

/**
 * 

* A simple TCP/IP-based HL7 server. This server listens for connections on a * particular port, and creates a ConnectionManager for each incoming * connection. *

*

* A single SimpleServer can only service requests that use a single class of * LowerLayerProtocol (specified at construction time). *

*

* The ConnectionManager uses a {@link PipeParser} of the version specified in * the constructor *

*

* ConnectionManagers currently only support original mode processing. *

*

* The ConnectionManager routes messages to various {@link Application}s based * on message type. From the HL7 perspective, an {@link Application} is * something that does something with a message. *

* * @author Bryan Tripp * @author Christian Ohr */ public class SimpleServer extends HL7Service { /** * Socket timeout for simple server */ public static final int SO_TIMEOUT = AcceptorThread.TIMEOUT; private static final Logger log = LoggerFactory.getLogger(SimpleServer.class); private int port; private boolean tls; private final BlockingQueue queue; private AcceptorThread acceptor; private HapiContext hapiContext; /** * Creates a new instance of SimpleServer that listens on the given port, * using the {@link MinLowerLayerProtocol} and a standard {@link PipeParser}. */ public SimpleServer(int port) { this(port, new MinLowerLayerProtocol(), new PipeParser(), false); } /** * Creates a new instance of SimpleServer that listens on the given port, * using the {@link MinLowerLayerProtocol} and a standard {@link PipeParser}. */ public SimpleServer(int port, boolean tls) { this(port, new MinLowerLayerProtocol(), new PipeParser(), tls); } /** * Creates a new instance of SimpleServer that listens on the given port. */ public SimpleServer(int port, LowerLayerProtocol llp, Parser parser) { this(port, llp, parser, false); } /** * Creates a new instance of SimpleServer that listens on the given port. */ public SimpleServer(int port, LowerLayerProtocol llp, Parser parser, boolean tls) { this(port, llp, parser, tls, DefaultExecutorService.getDefaultService()); } /** * Creates a new instance of SimpleServer using a custom {link * {@link ExecutorService}. This {@link ExecutorService} instance will * not be shut down after the server stops! */ public SimpleServer(int port, LowerLayerProtocol llp, Parser parser, boolean tls, ExecutorService executorService) { super(parser, llp, executorService); this.port = port; this.tls = tls; this.hapiContext = new DefaultHapiContext(); this.queue = new LinkedBlockingQueue(100); } /** * Creates a new instance of SimpleServer that listens on a given server socket. * SimpleServer will bind the socket when it is started, so the server socket * must not already be bound. * * @since 2.1 * @throws IllegalStateException If serverSocket is already bound */ public SimpleServer(HapiContext hapiContext, int port, boolean tls) { super(hapiContext); this.hapiContext = hapiContext; this.port = port; this.tls = tls; this.queue = new LinkedBlockingQueue(100); } /** * Prepare server by initializing the server socket * * @see ca.uhn.hl7v2.app.HL7Service#afterStartup() */ @Override protected void afterStartup() { try { super.afterStartup(); log.info("Starting SimpleServer running on port {}", port); SocketFactory ss = this.hapiContext.getSocketFactory(); acceptor = new AcceptorThread(port, tls, getExecutorService(), queue, ss); acceptor.start(); } catch (Exception e) { log.error("Failed starting SimpleServer on port", port); throw new RuntimeException(e); } } /** * Loop that waits for a connection and starts a ConnectionManager when it * gets one. */ @Override protected void handle() { if (acceptor.getServiceExitedWithException() != null) { setServiceExitedWithException(acceptor.getServiceExitedWithException()); } try { // Wait some period of time for connections AcceptedSocket newSocket = queue.poll(500, TimeUnit.MILLISECONDS); if (newSocket != null) { log.info("Accepted connection from {}:{} on local port {}", new Object[] { newSocket.socket.getInetAddress().getHostAddress(), newSocket.socket.getPort(), port }); ActiveConnection c = new ActiveConnection(getParser(), getLlp(), newSocket.socket, getExecutorService()); newConnection(c); } } catch (InterruptedException ie) { // just timed out } catch (Exception e) { log.error("Error while accepting connections: ", e); } } /** * Close down socket */ @Override protected void afterTermination() { super.afterTermination(); acceptor.stop(); } /** * Run server from command line. Port number should be passed as an * argument, and a file containing a list of Applications to use can also be * specified as an optional argument (as per * loadApplicationsFromFile(...)). Uses the default * LowerLayerProtocol. */ public static void main(String args[]) { if (args.length < 1 || args.length > 2) { System.out .println("Usage: ca.uhn.hl7v2.app.SimpleServer port_num [application_spec_file_name]"); System.exit(1); } int port = 0; try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("The given port (" + args[0] + ") is not an integer."); System.exit(1); } File appFile = null; if (args.length == 2) { appFile = new File(args[1]); } try { SimpleServer server = new SimpleServer(port); if (appFile != null) server.loadApplicationsFromFile(appFile); server.start(); } catch (Exception e) { e.printStackTrace(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy