From cabca5bd1dddc2fb8453a90d51d1932934082246 Mon Sep 17 00:00:00 2001
From: Gabriel Landais <glandais@kereval.com>
Date: Tue, 9 Aug 2011 09:41:11 +0000
Subject: [PATCH] New HL7 frame decoder

git-svn-id: https://scm.gforge.inria.fr/authscm/ycadoret/svn/gazelle/Maven/gazelle-proxy/trunk@23355 356b4b1a-1d2b-0410-8bf1-ffa24008f01e
---
 gazelle-proxy-netty/pom.xml                   | 10 ++-
 .../java/net/ihe/gazelle/proxy/netty/App.java | 16 ++---
 .../netty/protocols/hl7/AppHL7Client.java     | 29 ++++++++
 .../netty/protocols/hl7/AppHL7Server.java     | 35 ++++++++++
 .../netty/protocols/hl7/HL7FrameDecoder.java  | 70 +++++++++++++++++++
 .../netty/protocols/hl7/HL7ProxyConfig.java   | 16 ++---
 6 files changed, 157 insertions(+), 19 deletions(-)
 create mode 100644 gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Client.java
 create mode 100644 gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Server.java
 create mode 100644 gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7FrameDecoder.java

diff --git a/gazelle-proxy-netty/pom.xml b/gazelle-proxy-netty/pom.xml
index 4afa60c9..adbccf3d 100644
--- a/gazelle-proxy-netty/pom.xml
+++ b/gazelle-proxy-netty/pom.xml
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
 	<parent>
 		<groupId>net.ihe.gazelle.proxy</groupId>
@@ -25,7 +26,12 @@
 		<dependency>
 			<groupId>org.jboss.netty</groupId>
 			<artifactId>netty</artifactId>
-			<version>3.2.3.Final</version>
+			<version>3.2.5.Final</version>
+		</dependency>
+		<dependency>
+			<groupId>ca.uhn.hapi</groupId>
+			<artifactId>hapi-base</artifactId>
+			<version>1.2</version>
 		</dependency>
 		<dependency>
 			<groupId>jp.digitalsensation.ihej.transactionmonitor</groupId>
diff --git a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/App.java b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/App.java
index 9612e29a..9c698ffa 100644
--- a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/App.java
+++ b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/App.java
@@ -15,14 +15,8 @@ import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
 
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-
-import jp.digitalsensation.ihej.transactionmonitor.dicom.messageexchange.DimseMessage;
-import net.ihe.gazelle.proxy.netty.protocols.dicom.DicomEventListenerSimple;
-import net.ihe.gazelle.proxy.netty.protocols.dicom.DicomProxy;
-import net.ihe.gazelle.proxy.netty.protocols.http.HttpEventListenerSimple;
-import net.ihe.gazelle.proxy.netty.protocols.http.HttpProxy;
+import net.ihe.gazelle.proxy.netty.protocols.hl7.HL7EventListenerSimple;
+import net.ihe.gazelle.proxy.netty.protocols.hl7.HL7Proxy;
 import net.ihe.gazelle.proxy.netty.protocols.tls.AlwaysTrustManager;
 import net.ihe.gazelle.proxy.netty.protocols.tls.TlsConfig;
 import net.ihe.gazelle.proxy.netty.protocols.tls.TlsCredentials;
@@ -32,6 +26,7 @@ public class App {
 	public static void main(String[] args) throws Exception {
 		// testHttpsConnection();
 
+		/*
 		final ProxyEventListener<DimseMessage, DimseMessage> dicomProxyEvent = new DicomEventListenerSimple(System.out);
 		DicomProxy dicomProxy = new DicomProxy(dicomProxyEvent, 10012, "jumbo-4.irisa.fr", 10012, "/tmp/dicom", null);
 		dicomProxy.start();
@@ -39,6 +34,11 @@ public class App {
 		final ProxyEventListener<HttpRequest, HttpResponse> httpProxyEvent = new HttpEventListenerSimple(System.out);
 		HttpProxy httpProxy = new HttpProxy(httpProxyEvent, 8080, "jumbo-4.irisa.fr", 8080, null);
 		httpProxy.start();
+		*/
+
+		final ProxyEventListener<String, String> hl7ProxyEvent = new HL7EventListenerSimple(System.out);
+		HL7Proxy hl7Proxy = new HL7Proxy(hl7ProxyEvent, 10013, "127.0.0.1", 10014, null);
+		hl7Proxy.start();
 
 		// final ProxyEventListener<HttpRequest, HttpResponse> proxyEvent = new
 		// HttpEventListenerSimple(System.out);
diff --git a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Client.java b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Client.java
new file mode 100644
index 00000000..87167843
--- /dev/null
+++ b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Client.java
@@ -0,0 +1,29 @@
+package net.ihe.gazelle.proxy.netty.protocols.hl7;
+
+import java.net.Socket;
+
+import ca.uhn.hl7v2.llp.MinLLPWriter;
+
+public class AppHL7Client {
+
+	public static void main(String args[]) {
+		try {
+			Socket s = new Socket("127.0.0.1", 10013);
+			MinLLPWriter out = new MinLLPWriter(s.getOutputStream());
+			StringBuilder sb = new StringBuilder("");
+			for (int i = 0; i < 100000; i++) {
+				sb.append(i).append("Some message!\r");
+			}
+			String longMessage = sb.toString();
+			out.writeMessage(longMessage);
+			out.writeMessage("Some message2.");
+			out.writeMessage(longMessage);
+			out.writeMessage("Some message4.");
+			out.writeMessage(longMessage);
+			out.close();
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+	}
+
+}
diff --git a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Server.java b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Server.java
new file mode 100644
index 00000000..3ee21c60
--- /dev/null
+++ b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/AppHL7Server.java
@@ -0,0 +1,35 @@
+package net.ihe.gazelle.proxy.netty.protocols.hl7;
+
+import java.io.InterruptedIOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import ca.uhn.hl7v2.llp.MinLLPReader;
+
+public class AppHL7Server {
+
+	public static void main(String args[]) {
+		try {
+			ServerSocket ss = new ServerSocket(10014);
+			while (true) {
+				try {
+					Socket newSocket = ss.accept();
+					MinLLPReader in = new MinLLPReader(newSocket.getInputStream());
+					String str = null;
+					do {
+						str = in.getMessage();
+						System.out.println(str);
+					} while (str != null);
+
+				} catch (InterruptedIOException ie) {
+					ie.printStackTrace();
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		} catch (Exception e) {
+			System.out.println(e);
+		}
+	}
+
+}
diff --git a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7FrameDecoder.java b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7FrameDecoder.java
new file mode 100644
index 00000000..29829764
--- /dev/null
+++ b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7FrameDecoder.java
@@ -0,0 +1,70 @@
+package net.ihe.gazelle.proxy.netty.protocols.hl7;
+
+import java.io.ByteArrayOutputStream;
+
+import org.apache.log4j.Logger;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.jboss.netty.util.CharsetUtil;
+
+public class HL7FrameDecoder extends FrameDecoder {
+
+	private static Logger log = Logger.getLogger(HL7FrameDecoder.class);
+
+	// character indicating the start of an HL7 message
+	private static final char START_MESSAGE = '\u000b';
+
+	// character indicating the termination of an HL7 message
+	private static final char END_MESSAGE = '\u001c';
+
+	// the final character of a message: a carriage return
+	private static final char LAST_CHARACTER = 13;
+
+	private static final int STATUS_INIT = 0;
+	private static final int STATUS_READ = 1;
+	private static final int STATUS_END = 2;
+
+	private int status = 0;
+	private ByteArrayOutputStream currentFrame = null;
+
+	@Override
+	protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
+		while (buffer.readableBytes() > 0) {
+			byte readByte = buffer.readByte();
+			switch (status) {
+			case STATUS_INIT:
+				if (readByte == START_MESSAGE) {
+					log.info("START_MESSAGE");
+					status = STATUS_READ;
+					currentFrame = new ByteArrayOutputStream();
+				}
+				break;
+			case STATUS_READ:
+				if (readByte == END_MESSAGE) {
+					log.info("END_MESSAGE");
+					status = STATUS_END;
+					return currentFrame.toString(CharsetUtil.UTF_8.name());
+				} else {
+					currentFrame.write(readByte);
+				}
+				break;
+			case STATUS_END:
+				if (readByte == LAST_CHARACTER) {
+					status = STATUS_INIT;
+				}
+				if (readByte == START_MESSAGE) {
+					log.info("START_MESSAGE");
+					status = STATUS_READ;
+					currentFrame = new ByteArrayOutputStream();
+				}
+				break;
+			default:
+				break;
+			}
+		}
+
+		return null;
+	}
+}
diff --git a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7ProxyConfig.java b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7ProxyConfig.java
index ba52fa10..04cba67d 100644
--- a/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7ProxyConfig.java
+++ b/gazelle-proxy-netty/src/main/java/net/ihe/gazelle/proxy/netty/protocols/hl7/HL7ProxyConfig.java
@@ -13,8 +13,6 @@ import org.jboss.netty.buffer.ChannelBuffers;
 import org.jboss.netty.channel.Channel;
 import org.jboss.netty.channel.ChannelHandler;
 import org.jboss.netty.channel.socket.ClientSocketChannelFactory;
-import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
-import org.jboss.netty.util.CharsetUtil;
 
 public class HL7ProxyConfig extends ProxyConfigAbstract<String, String> {
 
@@ -27,7 +25,7 @@ public class HL7ProxyConfig extends ProxyConfigAbstract<String, String> {
 		List<ChannelHandler> channels = new ArrayList<ChannelHandler>();
 
 		// Decode HL7 messages
-		channels.add(new DelimiterBasedFrameDecoder(1024 * 1024, getHL7Delimiter()));
+		channels.add(new HL7FrameDecoder());
 
 		return channels;
 	}
@@ -42,16 +40,16 @@ public class HL7ProxyConfig extends ProxyConfigAbstract<String, String> {
 
 	public void handleMessage(Object message, ProxySide proxySide, String requesterIp, int requesterPort,
 			Channel requestChannel) {
-		if (message instanceof ChannelBuffer) {
-			ChannelBuffer cb = (ChannelBuffer) message;
-			// Removes the 0x0B at the beginning
-			String result = cb.toString(1, cb.readableBytes() - 1, CharsetUtil.UTF_8);
+		if (message instanceof String) {
+			String result = (String) message;
 			switch (proxySide) {
 			case REQUEST:
-				eventListener.onRequest(result, requesterIp, requesterPort, getRemoteHost(), getRemotePort(), requestChannel.getId());
+				eventListener.onRequest(result, requesterIp, requesterPort, getRemoteHost(), getRemotePort(),
+						requestChannel.getId());
 				break;
 			case RESPONSE:
-				eventListener.onResponse(result, requesterIp, requesterPort, getRemoteHost(), getRemotePort(), requestChannel.getId());
+				eventListener.onResponse(result, requesterIp, requesterPort, getRemoteHost(), getRemotePort(),
+						requestChannel.getId());
 				break;
 			}
 		}
-- 
GitLab