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
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
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
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
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
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
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
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 }