View Javadoc

1   package ca.uhn.hl7v2.hoh.llp;
2   
3   import static org.junit.Assert.*;
4   
5   import java.io.BufferedReader;
6   import java.io.DataOutputStream;
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.io.InputStreamReader;
10  import java.net.HttpURLConnection;
11  import java.net.URL;
12  import java.nio.charset.Charset;
13  import java.util.Map;
14  import java.util.Map.Entry;
15  
16  import ca.uhn.hl7v2.protocol.ReceivingApplication;
17  import ca.uhn.hl7v2.protocol.ReceivingApplicationException;
18  import org.junit.After;
19  import org.junit.Before;
20  import org.junit.Test;
21  
22  import ca.uhn.hl7v2.AcknowledgmentCode;
23  import ca.uhn.hl7v2.HL7Exception;
24  import ca.uhn.hl7v2.app.Application;
25  import ca.uhn.hl7v2.app.ApplicationException;
26  import ca.uhn.hl7v2.app.Connection;
27  import ca.uhn.hl7v2.app.ConnectionListener;
28  import ca.uhn.hl7v2.app.SimpleServer;
29  import ca.uhn.hl7v2.hoh.encoder.EncodingStyle;
30  import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestEncoder;
31  import ca.uhn.hl7v2.hoh.sign.BouncyCastleCmsMessageSignerTest;
32  import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider;
33  import ca.uhn.hl7v2.hoh.util.ServerRoleEnum;
34  import ca.uhn.hl7v2.model.Message;
35  import ca.uhn.hl7v2.parser.DefaultXMLParser;
36  import ca.uhn.hl7v2.parser.GenericParser;
37  import ca.uhn.hl7v2.parser.PipeParser;
38  
39  public class LlpServerTest implements ReceivingApplication<Message>, ConnectionListener {
40  
41  	private int myPort;
42  	private Hl7OverHttpLowerLayerProtocol myLlp;
43  	private SimpleServer myServer;
44  	private Message myMessage;
45  	private int myConnections;
46  	private Message myResponse;
47  
48  	@Before
49  	public void before() throws InterruptedException {
50  		myPort = RandomServerPortProvider.findFreePort();
51  
52  		myLlp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.SERVER);
53  		myServer = new SimpleServer(myPort, myLlp, GenericParser.getInstanceWithNoValidation());
54  		myServer.registerApplication("*", "*", this);
55  		myServer.registerConnectionListener(this);
56  		myMessage = (Message) null;
57  		myResponse = (Message) null;
58  		myConnections = 0;
59  	}
60  
61  	@Test
62  	public void testSendSimple() throws Exception {
63  		myServer.startAndWait();
64  
65  		String message = // -
66  		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
67  				"EVN||200803051509\r" + // -
68  				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
69  
70  		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
71  		String charsetName = "ISO-8859-2";
72  		enc.setCharset(Charset.forName(charsetName));
73  		enc.setUsername("hello");
74  		enc.setPassword("world");
75  		enc.setMessage(message);
76  		enc.encode();
77  
78  		String urlString = "http://localhost:" + myPort + "/";
79  		ourLog.info("URL: {}", urlString);
80  		URL url = new URL(urlString);
81  		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
82  		conn.setRequestMethod("POST");
83  
84  		conn.setUseCaches(false);
85  		conn.setDoInput(true);
86  		conn.setDoOutput(true);
87  		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
88  			conn.setRequestProperty(next.getKey(), next.getValue());
89  		}
90  
91  		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
92  		wr.write(enc.getData());
93  		wr.flush();
94  
95  		// Get Response
96  		InputStream is = conn.getInputStream();
97  		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
98  		String line;
99  		StringBuffer response = new StringBuffer();
100 		while ((line = rd.readLine()) != null) {
101 			response.append(line);
102 			response.append('\r');
103 		}
104 		String responseString = response.toString();
105 		ourLog.info("Response:\n{}", responseString);
106 
107 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
108 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
109 		assertEquals(200, conn.getResponseCode());
110 		assertEquals(message, myMessage.encode());
111 		assertEquals(myResponse.encode(), responseString);
112 
113 	}
114 
115 	@Test
116 	public void testSendSimpleXml() throws Exception {
117 		myServer.startAndWait();
118 
119 		String message = // -
120 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
121 				"EVN||200803051509\r" + // -
122 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
123 		message = DefaultXMLParser.getInstanceWithNoValidation().encode(PipeParser.getInstanceWithNoValidation().parse(message));
124 		
125 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
126 		String charsetName = "ISO-8859-2";
127 		enc.setCharset(Charset.forName(charsetName));
128 		enc.setUsername("hello");
129 		enc.setPassword("world");
130 		enc.setMessage(message);
131 		enc.encode();
132 
133 		String urlString = "http://localhost:" + myPort + "/";
134 		ourLog.info("URL: {}", urlString);
135 		URL url = new URL(urlString);
136 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
137 		conn.setRequestMethod("POST");
138 
139 		conn.setUseCaches(false);
140 		conn.setDoInput(true);
141 		conn.setDoOutput(true);
142 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
143 			conn.setRequestProperty(next.getKey(), next.getValue());
144 		}
145 
146 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
147 		wr.write(enc.getData());
148 		wr.flush();
149 
150 		// Get Response
151 		InputStream is = conn.getInputStream();
152 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
153 		String line;
154 		StringBuffer response = new StringBuffer();
155 		while ((line = rd.readLine()) != null) {
156 			response.append(line);
157 			response.append('\r');
158 		}
159 		String responseString = response.toString();
160 		ourLog.info("Response:\n{}", responseString);
161 
162 		assertEquals(EncodingStyle.XML.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
163 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
164 		assertEquals(200, conn.getResponseCode());
165 		assertEquals(message, myMessage.encode());
166 		
167 		String expected = myResponse.encode().replaceAll("<\\?.*\\?>", "").replaceAll("(\\r|\\n)+", "\n").trim();
168 		String actual = responseString.replaceAll("<\\?.*\\?>", "").replaceAll("(\\r|\\n)+", "\n").trim();
169 		assertEquals(expected, actual);
170 
171 	}
172 
173 	@Test
174 	public void testReplyWithAE() throws Exception {
175 		myServer.startAndWait();
176 
177 		String message = // -
178 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
179 				"EVN||200803051509\r" + // -
180 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
181 
182 		myResponse = PipeParser.getInstanceWithNoValidation().parse(message).generateACK(AcknowledgmentCode.AE, new HL7Exception("blah"));
183 		
184 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
185 		String charsetName = "ISO-8859-2";
186 		enc.setCharset(Charset.forName(charsetName));
187 		enc.setUsername("hello");
188 		enc.setPassword("world");
189 		enc.setMessage(message);
190 		enc.encode();
191 
192 		String urlString = "http://localhost:" + myPort + "/";
193 		ourLog.info("URL: {}", urlString);
194 		URL url = new URL(urlString);
195 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
196 		conn.setRequestMethod("POST");
197 
198 		conn.setUseCaches(false);
199 		conn.setDoInput(true);
200 		conn.setDoOutput(true);
201 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
202 			conn.setRequestProperty(next.getKey(), next.getValue());
203 		}
204 
205 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
206 		wr.write(enc.getData());
207 		wr.flush();
208 
209 		// Get Response
210 		InputStream is;
211 		try {
212 			is = conn.getInputStream();
213 		} catch (IOException e) {
214 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
215 				is = conn.getErrorStream();
216 			} else {
217 				throw e;
218 			}
219 		}
220 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
221 		String line;
222 		StringBuffer response = new StringBuffer();
223 		while ((line = rd.readLine()) != null) {
224 			response.append(line);
225 			response.append('\r');
226 		}
227 		String responseString = response.toString();
228 		ourLog.info("Response:\n{}", responseString);
229 
230 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
231 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
232 		assertEquals(200, conn.getResponseCode());
233 		assertEquals(message, myMessage.encode());
234 		assertEquals(myResponse.encode(), responseString);
235 
236 	}
237 
238 	@Test
239 	public void testReplyWithAR() throws Exception {
240 		myServer.startAndWait();
241 
242 		String message = // -
243 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
244 				"EVN||200803051509\r" + // -
245 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
246 
247 		myResponse = PipeParser.getInstanceWithNoValidation().parse(message)
248 				.generateACK(AcknowledgmentCode.AR, new HL7Exception("blah"));
249 		
250 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
251 		String charsetName = "ISO-8859-2";
252 		enc.setCharset(Charset.forName(charsetName));
253 		enc.setUsername("hello");
254 		enc.setPassword("world");
255 		enc.setMessage(message);
256 		enc.encode();
257 
258 		String urlString = "http://localhost:" + myPort + "/";
259 		ourLog.info("URL: {}", urlString);
260 		URL url = new URL(urlString);
261 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
262 		conn.setRequestMethod("POST");
263 
264 		conn.setUseCaches(false);
265 		conn.setDoInput(true);
266 		conn.setDoOutput(true);
267 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
268 			conn.setRequestProperty(next.getKey(), next.getValue());
269 		}
270 
271 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
272 		wr.write(enc.getData());
273 		wr.flush();
274 
275 		// Get Response
276 		InputStream is;
277 		try {
278 			is = conn.getInputStream();
279 		} catch (IOException e) {
280 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
281 				is = conn.getErrorStream();
282 			} else {
283 				throw e;
284 			}
285 		}
286 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
287 		String line;
288 		StringBuffer response = new StringBuffer();
289 		while ((line = rd.readLine()) != null) {
290 			response.append(line);
291 			response.append('\r');
292 		}
293 		String responseString = response.toString();
294 		ourLog.info("Response:\n{}", responseString);
295 
296 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
297 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
298 		assertEquals(200, conn.getResponseCode());
299 		assertEquals(message, myMessage.encode());
300 		assertEquals(myResponse.encode(), responseString);
301 
302 	}
303 	
304 	@Test
305 	public void testSendPersistentConnection() throws Exception {
306 		myServer.startAndWait();
307 
308 		String message = // -
309 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
310 				"EVN||200803051509\r" + // -
311 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
312 
313 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
314 		enc.setCharset(Charset.forName("ISO-8859-1"));
315 		enc.setUsername("hello");
316 		enc.setPassword("world");
317 		enc.setMessage(message);
318 		enc.encode();
319 
320 		String urlString = "http://localhost:" + myPort + "/";
321 		ourLog.info("URL: {}", urlString);
322 		URL url = new URL(urlString);
323 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
324 		conn.setRequestMethod("POST");
325 
326 		conn.setUseCaches(false);
327 		conn.setDoInput(true);
328 		conn.setDoOutput(true);
329 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
330 			conn.setRequestProperty(next.getKey(), next.getValue());
331 		}
332 
333 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
334 		wr.write(enc.getData());
335 		wr.flush();
336 		wr.close();
337 
338 		// Get Response
339 		InputStream is = conn.getInputStream();
340 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
341 		String line;
342 		StringBuffer response = new StringBuffer();
343 		while ((line = rd.readLine()) != null) {
344 			response.append(line);
345 			response.append('\r');
346 		}
347 		is.close();
348 		String responseString = response.toString();
349 		ourLog.info("Response:\n{}", responseString);
350 
351 		assertEquals(200, conn.getResponseCode());
352 		assertEquals(message, myMessage.encode());
353 		assertEquals(myResponse.encode(), responseString);
354 
355 		// Send a second message
356 		message = // -
357 		"MSH|^~\\&|||||200803051508||ADT^A31|99999|P|2.5\r" + // -
358 				"EVN||200803051509\r" + // -
359 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
360 
361 		enc = new Hl7OverHttpRequestEncoder();
362 		enc.setCharset(Charset.forName("ISO-8859-1"));
363 		enc.setUsername("hello");
364 		enc.setPassword("world");
365 		enc.setMessage(message);
366 		enc.encode();
367 
368 		conn = (HttpURLConnection) url.openConnection();
369 		conn.setRequestMethod("POST");
370 
371 		conn.setUseCaches(false);
372 		conn.setDoInput(true);
373 		conn.setDoOutput(true);
374 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
375 			conn.setRequestProperty(next.getKey(), next.getValue());
376 		}
377 
378 		wr = new DataOutputStream(conn.getOutputStream());
379 		wr.write(enc.getData());
380 		wr.flush();
381 
382 		// Get Response
383 		is = conn.getInputStream();
384 		rd = new BufferedReader(new InputStreamReader(is));
385 		response = new StringBuffer();
386 		while ((line = rd.readLine()) != null) {
387 			response.append(line);
388 			response.append('\r');
389 		}
390 		responseString = response.toString();
391 		ourLog.info("Response:\n{}", responseString);
392 
393 		assertEquals(200, conn.getResponseCode());
394 		assertEquals(message, myMessage.encode());
395 		assertEquals(myResponse.encode(), responseString);
396 		assertEquals(1, myConnections);
397 	}
398 
399 	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(LlpServerTest.class);
400 
401 	@After
402 	public void after() {
403 		myServer.stopAndWait();
404 	}
405 
406 	public boolean canProcess(Message theArg0) {
407 		return true;
408 	}
409 
410 	public Message processMessage(Message theArg0, Map<String, Object> metadata)
411             throws ReceivingApplicationException, HL7Exception {
412 		myMessage = theArg0;
413 		if (myResponse != null) {
414 			return myResponse;
415 		}
416 		try {
417 			myResponse = theArg0.generateACK();
418 			return myResponse;
419 		} catch (IOException e) {
420 			fail(e.getMessage());
421 			throw new HL7Exception(e);
422 		}
423 	}
424 
425 	public void connectionDiscarded(Connection theArg0) {
426 		// ignore
427 	}
428 
429 	public void connectionReceived(Connection theArg0) {
430 		myConnections++;
431 	}
432 
433 	
434 	@Test
435 	public void testSendWithClientSigner() throws Exception {
436 		myLlp.setSigner(BouncyCastleCmsMessageSignerTest.createVerifier());
437 		myServer.startAndWait();
438 
439 		String message = // -
440 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
441 				"EVN||200803051509\r" + // -
442 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
443 
444 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
445 		enc.setCharset(Charset.forName("ISO-8859-1"));
446 		enc.setUsername("hello");
447 		enc.setPassword("world");
448 		enc.setMessage(message);
449 		enc.setSigner(BouncyCastleCmsMessageSignerTest.createSigner());
450 		enc.encode();
451 
452 		String urlString = "http://localhost:" + myPort + "/";
453 		ourLog.info("URL: {}", urlString);
454 		URL url = new URL(urlString);
455 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
456 		conn.setRequestMethod("POST");
457 
458 		conn.setUseCaches(false);
459 		conn.setDoInput(true);
460 		conn.setDoOutput(true);
461 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
462 			conn.setRequestProperty(next.getKey(), next.getValue());
463 		}
464 
465 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
466 		wr.write(enc.getData());
467 		wr.flush();
468 
469 		// Get Response
470 		InputStream is = conn.getInputStream();
471 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
472 		String line;
473 		StringBuffer response = new StringBuffer();
474 		while ((line = rd.readLine()) != null) {
475 			response.append(line);
476 			response.append('\r');
477 		}
478 		String responseString = response.toString();
479 		ourLog.info("Response:\n{}", responseString);
480 
481 		assertEquals(200, conn.getResponseCode());
482 		assertEquals(message, myMessage.encode());
483 		assertEquals(myResponse.encode(), responseString);
484 
485 	}
486 
487 }