View Javadoc

1   package ca.uhn.hl7v2.hoh.raw.server;
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.Entry;
14  
15  import org.junit.After;
16  import org.junit.AfterClass;
17  import org.junit.Before;
18  import org.junit.BeforeClass;
19  import org.junit.Test;
20  import org.mortbay.jetty.Server;
21  import org.mortbay.jetty.servlet.Context;
22  import org.mortbay.jetty.servlet.ServletHolder;
23  
24  import ca.uhn.hl7v2.AcknowledgmentCode;
25  import ca.uhn.hl7v2.DefaultHapiContext;
26  import ca.uhn.hl7v2.HL7Exception;
27  import ca.uhn.hl7v2.hoh.api.IAuthorizationServerCallback;
28  import ca.uhn.hl7v2.hoh.api.IMessageHandler;
29  import ca.uhn.hl7v2.hoh.api.IReceivable;
30  import ca.uhn.hl7v2.hoh.api.IResponseSendable;
31  import ca.uhn.hl7v2.hoh.api.MessageProcessingException;
32  import ca.uhn.hl7v2.hoh.encoder.EncodingStyle;
33  import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestEncoder;
34  import ca.uhn.hl7v2.hoh.llp.Hl7OverHttpLowerLayerProtocol;
35  import ca.uhn.hl7v2.hoh.raw.api.RawSendable;
36  import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider;
37  import ca.uhn.hl7v2.hoh.util.ServerRoleEnum;
38  import ca.uhn.hl7v2.hoh.util.StringUtils;
39  import ca.uhn.hl7v2.model.v25.message.ADT_A05;
40  import ca.uhn.hl7v2.parser.DefaultXMLParser;
41  import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
42  import ca.uhn.hl7v2.parser.GenericParser;
43  
44  public class HohRawServletTest implements IAuthorizationServerCallback, IMessageHandler<String> {
45  
46  	private static DefaultHapiContext ourHapiContext;
47  	private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawServletTest.class);
48  	private String myExpectedPassword;
49  	private String myExpectedUri;
50  	private String myExpectedUsername;
51  	private String myMessage;
52  	private String myResponse;
53  	private int myPort;
54  	private Server myServer;
55  
56  	@After
57  	public void after() throws Exception {
58  		myServer.stop();
59  	}
60  
61  	public boolean authorize(String theUri, String theUsername, String thePassword) {
62  		if (myExpectedUsername == null) {
63  			return true;
64  		} else {
65  			if (!StringUtils.equals(myExpectedUri, theUri)) {
66  				return false;
67  			}
68  			if (!StringUtils.equals(myExpectedUsername, theUsername)) {
69  				return false;
70  			}
71  			if (!StringUtils.equals(myExpectedPassword, thePassword)) {
72  				return false;
73  			}
74  			return true;
75  		}
76  
77  	}
78  
79  	@Before
80  	public void before() throws Exception {
81  		myPort = RandomServerPortProvider.findFreePort();
82  		myServer = new Server(myPort);
83  		Context context = new Context(myServer, "/", Context.SESSIONS);
84  		HohRawServlet servlet = new HohRawServlet();
85  		servlet.setAuthorizationCallback(this);
86  		servlet.setMessageHandler(this);
87  		context.addServlet(new ServletHolder(servlet), "/*");
88  
89  		myServer.start();
90  
91  		while (myServer.isStarting()) {
92  			ourLog.info("Waiting for server to start...");
93  			Thread.sleep(100);
94  		}
95  
96  		myResponse = null;
97  	}
98  
99  	public IResponseSendable<String> messageReceived(IReceivable<String> theMessage) throws MessageProcessingException {
100 
101 		myMessage = theMessage.getMessage();
102 		try {
103 			if (myResponse == null) {
104 				myResponse = GenericParser.getInstanceWithNoValidation().parse(myMessage).generateACK().encode();
105 			}
106 			return new RawSendable(myResponse);
107 		} catch (EncodingNotSupportedException e) {
108 			throw new MessageProcessingException(e);
109 		} catch (HL7Exception e) {
110 			throw new MessageProcessingException(e);
111 		} catch (IOException e) {
112 			throw new MessageProcessingException(e);
113 		}
114 
115 	}
116 
117 	@Test
118 	public void testSuccessWhenRequestHasNoCharsetSpecified() throws Exception {
119 
120 		String message = // -
121 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
122 				"EVN||200803051509\r" + // -
123 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
124 		ADT_A05 msg = new ADT_A05();
125 		msg.parse(message);
126 
127 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
128 		String charsetName = "ISO-8859-1";
129 		llp.setPreferredCharset(Charset.forName(charsetName));
130 
131 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
132 		enc.setCharset(Charset.forName(charsetName));
133 		enc.setUsername("hello");
134 		enc.setPassword("world");
135 		enc.setMessage(message);
136 		enc.encode();
137 
138 		String urlString = "http://localhost:" + myPort + "/";
139 		ourLog.info("URL: {}", urlString);
140 		URL url = new URL(urlString);
141 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
142 		conn.setRequestMethod("POST");
143 
144 		conn.setUseCaches(false);
145 		conn.setDoInput(true);
146 		conn.setDoOutput(true);
147 
148 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
149 			if (next.getKey().toLowerCase().equals("content-type")) {
150 				conn.setRequestProperty(next.getKey(), "application/hl7-v2");
151 			} else {
152 				conn.setRequestProperty(next.getKey(), next.getValue());
153 			}
154 		}
155 
156 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
157 		wr.write(enc.getData());
158 		wr.flush();
159 
160 		// Get Response
161 		InputStream is;
162 		try {
163 			is = conn.getInputStream();
164 		} catch (IOException e) {
165 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
166 				is = conn.getErrorStream();
167 			} else {
168 				throw e;
169 			}
170 		}
171 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
172 		String line;
173 		StringBuffer response = new StringBuffer();
174 		while ((line = rd.readLine()) != null) {
175 			response.append(line);
176 			response.append('\r');
177 		}
178 		String responseString = response.toString();
179 		ourLog.info("Response:\n{}", responseString);
180 
181 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
182 		assertEquals("UTF-8", conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
183 		assertEquals(200, conn.getResponseCode());
184 		assertEquals(message, myMessage);
185 		assertEquals(myResponse, responseString);
186 	}
187 
188 	@Test
189 	public void testServlet() throws Exception {
190 
191 		String message = // -
192 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
193 				"EVN||200803051509\r" + // -
194 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
195 		ADT_A05 msg = new ADT_A05();
196 		msg.parse(message);
197 
198 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
199 		String charsetName = "ISO-8859-2";
200 		llp.setPreferredCharset(Charset.forName(charsetName));
201 
202 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
203 		enc.setCharset(Charset.forName(charsetName));
204 		enc.setUsername("hello");
205 		enc.setPassword("world");
206 		enc.setMessage(message);
207 		enc.encode();
208 
209 		String urlString = "http://localhost:" + myPort + "/";
210 		ourLog.info("URL: {}", urlString);
211 		URL url = new URL(urlString);
212 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
213 		conn.setRequestMethod("POST");
214 
215 		conn.setUseCaches(false);
216 		conn.setDoInput(true);
217 		conn.setDoOutput(true);
218 
219 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
220 			conn.setRequestProperty(next.getKey(), next.getValue());
221 		}
222 
223 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
224 		wr.write(enc.getData());
225 		wr.flush();
226 
227 		// Get Response
228 		InputStream is;
229 		try {
230 			is = conn.getInputStream();
231 		} catch (IOException e) {
232 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
233 				is = conn.getErrorStream();
234 			} else {
235 				throw e;
236 			}
237 		}
238 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
239 		String line;
240 		StringBuffer response = new StringBuffer();
241 		while ((line = rd.readLine()) != null) {
242 			response.append(line);
243 			response.append('\r');
244 		}
245 		String responseString = response.toString();
246 		ourLog.info("Response:\n{}", responseString);
247 
248 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
249 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
250 		assertEquals(200, conn.getResponseCode());
251 		assertEquals(message, myMessage);
252 		assertEquals(myResponse, responseString);
253 
254 	}
255 
256 	@Test
257 	public void testLargeMessage() throws Exception {
258 
259 		StringBuilder b= new StringBuilder();
260 		for (int a = 0; a < 100000; a++) {
261 			b.append('a');
262 		}
263 		
264 		String message = // -
265 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
266 				"EVN||200803051509\r" + // -
267 				"PID|||" + b + "^^^SSN^SSN^^20070103\r"; // -
268 		ADT_A05 msg = new ADT_A05();
269 		msg.parse(message);
270 
271 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
272 		String charsetName = "ISO-8859-2";
273 		llp.setPreferredCharset(Charset.forName(charsetName));
274 
275 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
276 		enc.setCharset(Charset.forName(charsetName));
277 		enc.setUsername("hello");
278 		enc.setPassword("world");
279 		enc.setMessage(message);
280 		enc.encode();
281 
282 		String urlString = "http://localhost:" + myPort + "/";
283 		ourLog.info("URL: {}", urlString);
284 		URL url = new URL(urlString);
285 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
286 		conn.setRequestMethod("POST");
287 
288 		conn.setUseCaches(false);
289 		conn.setDoInput(true);
290 		conn.setDoOutput(true);
291 
292 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
293 			conn.setRequestProperty(next.getKey(), next.getValue());
294 		}
295 
296 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
297 		wr.write(enc.getData());
298 		wr.flush();
299 
300 		// Get Response
301 		InputStream is;
302 		try {
303 			is = conn.getInputStream();
304 		} catch (IOException e) {
305 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
306 				is = conn.getErrorStream();
307 			} else {
308 				throw e;
309 			}
310 		}
311 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
312 		String line;
313 		StringBuffer response = new StringBuffer();
314 		while ((line = rd.readLine()) != null) {
315 			response.append(line);
316 			response.append('\r');
317 		}
318 		String responseString = response.toString();
319 		ourLog.info("Response:\n{}", responseString);
320 
321 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
322 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
323 		assertEquals(200, conn.getResponseCode());
324 		assertEquals(message, myMessage);
325 		assertEquals(myResponse, responseString);
326 
327 	}
328 
329 	@Test
330 	public void testServletAR() throws Exception {
331 
332 		String message = // -
333 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
334 				"EVN||200803051509\r" + // -
335 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
336 		ADT_A05 msg = new ADT_A05();
337 		msg.parse(message);
338 
339 		myResponse = msg.generateACK(AcknowledgmentCode.AR, new HL7Exception("ewrerwe")).encode();
340 
341 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
342 		String charsetName = "ISO-8859-2";
343 		llp.setPreferredCharset(Charset.forName(charsetName));
344 
345 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
346 		enc.setCharset(Charset.forName(charsetName));
347 		enc.setUsername("hello");
348 		enc.setPassword("world");
349 		enc.setMessage(message);
350 		enc.encode();
351 
352 		String urlString = "http://localhost:" + myPort + "/";
353 		ourLog.info("URL: {}", urlString);
354 		URL url = new URL(urlString);
355 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
356 		conn.setRequestMethod("POST");
357 
358 		conn.setUseCaches(false);
359 		conn.setDoInput(true);
360 		conn.setDoOutput(true);
361 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
362 			conn.setRequestProperty(next.getKey(), next.getValue());
363 		}
364 
365 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
366 		wr.write(enc.getData());
367 		wr.flush();
368 
369 		// Get Response
370 		InputStream is;
371 		try {
372 			is = conn.getInputStream();
373 		} catch (IOException e) {
374 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
375 				is = conn.getErrorStream();
376 			} else {
377 				throw e;
378 			}
379 		}
380 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
381 		String line;
382 		StringBuffer response = new StringBuffer();
383 		while ((line = rd.readLine()) != null) {
384 			response.append(line);
385 			response.append('\r');
386 		}
387 		String responseString = response.toString();
388 		ourLog.info("Response:\n{}", responseString);
389 
390 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
391 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
392 		assertEquals(200, conn.getResponseCode());
393 		assertEquals(message, myMessage);
394 		assertEquals(myResponse, responseString);
395 
396 	}
397 
398 	@Test
399 	public void testServletAE() throws Exception {
400 
401 		String message = // -
402 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
403 				"EVN||200803051509\r" + // -
404 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
405 		ADT_A05 msg = new ADT_A05();
406 		msg.parse(message);
407 
408 		myResponse = msg.generateACK(AcknowledgmentCode.AE, new HL7Exception("ewrerwe")).encode();
409 
410 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
411 		String charsetName = "ISO-8859-2";
412 		llp.setPreferredCharset(Charset.forName(charsetName));
413 
414 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
415 		enc.setCharset(Charset.forName(charsetName));
416 		enc.setUsername("hello");
417 		enc.setPassword("world");
418 		enc.setMessage(message);
419 		enc.encode();
420 
421 		String urlString = "http://localhost:" + myPort + "/";
422 		ourLog.info("URL: {}", urlString);
423 		URL url = new URL(urlString);
424 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
425 		conn.setRequestMethod("POST");
426 
427 		conn.setUseCaches(false);
428 		conn.setDoInput(true);
429 		conn.setDoOutput(true);
430 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
431 			conn.setRequestProperty(next.getKey(), next.getValue());
432 		}
433 
434 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
435 		wr.write(enc.getData());
436 		wr.flush();
437 
438 		// Get Response
439 		InputStream is;
440 		try {
441 			is = conn.getInputStream();
442 		} catch (IOException e) {
443 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
444 				is = conn.getErrorStream();
445 			} else {
446 				throw e;
447 			}
448 		}
449 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
450 		String line;
451 		StringBuffer response = new StringBuffer();
452 		while ((line = rd.readLine()) != null) {
453 			response.append(line);
454 			response.append('\r');
455 		}
456 		String responseString = response.toString();
457 		ourLog.info("Response:\n{}", responseString);
458 
459 		assertEquals(EncodingStyle.ER7.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
460 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
461 		assertEquals(200, conn.getResponseCode());
462 		assertEquals(message, myMessage);
463 		assertEquals(myResponse, responseString);
464 
465 	}
466 
467 	@Test
468 	public void testServletSimpleXml() throws Exception {
469 
470 		String message = // -
471 		"MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
472 				"EVN||200803051509\r" + // -
473 				"PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
474 		ADT_A05 msg = new ADT_A05();
475 		msg.parse(message);
476 
477 		message = DefaultXMLParser.getInstanceWithNoValidation().encode(msg);
478 
479 		Hl7OverHttpLowerLayerProtocol llp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
480 		String charsetName = "ISO-8859-2";
481 		llp.setPreferredCharset(Charset.forName(charsetName));
482 
483 		Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder();
484 		enc.setCharset(Charset.forName(charsetName));
485 		enc.setUsername("hello");
486 		enc.setPassword("world");
487 		enc.setMessage(message);
488 		enc.encode();
489 
490 		String urlString = "http://localhost:" + myPort + "/";
491 		ourLog.info("URL: {}", urlString);
492 		URL url = new URL(urlString);
493 		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
494 		conn.setRequestMethod("POST");
495 
496 		conn.setUseCaches(false);
497 		conn.setDoInput(true);
498 		conn.setDoOutput(true);
499 		for (Entry<String, String> next : enc.getHeaders().entrySet()) {
500 			conn.setRequestProperty(next.getKey(), next.getValue());
501 		}
502 
503 		DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
504 		wr.write(enc.getData());
505 		wr.flush();
506 
507 		// Get Response
508 		InputStream is;
509 		try {
510 			is = conn.getInputStream();
511 		} catch (IOException e) {
512 			if (conn.getResponseCode() == 400 || conn.getResponseCode() == 500) {
513 				is = conn.getErrorStream();
514 			} else {
515 				throw e;
516 			}
517 		}
518 		BufferedReader rd = new BufferedReader(new InputStreamReader(is));
519 		String line;
520 		StringBuffer response = new StringBuffer();
521 		while ((line = rd.readLine()) != null) {
522 			response.append(line);
523 			response.append('\r');
524 		}
525 		String responseString = response.toString();
526 		ourLog.info("Response:\n{}", responseString);
527 
528 		assertEquals(EncodingStyle.XML.getContentType(), conn.getHeaderField("Content-Type").replaceAll(";.*", ""));
529 		assertEquals(charsetName, conn.getHeaderField("Content-Type").replaceAll(".*;.*charset=", ""));
530 		assertEquals(200, conn.getResponseCode());
531 		assertEquals(message, myMessage);
532 		assertEquals(myResponse.replaceAll("(\\r|\\n)+", " "), responseString.replaceAll("(\\r|\\n)+", " "));
533 
534 	}
535 
536 	@AfterClass
537 	public static void afterClass() throws InterruptedException {
538 		// Thread.sleep(1000000);
539 		ourHapiContext.getExecutorService().shutdown();
540 	}
541 
542 	@BeforeClass
543 	public static void beforeClass() {
544 		System.setProperty("DEBUG", "true");
545 
546 		ourHapiContext = new DefaultHapiContext();
547 	}
548 
549 }