001package ca.uhn.hl7v2.hoh.raw.server; 002 003import static org.junit.Assert.*; 004 005import java.io.BufferedReader; 006import java.io.DataOutputStream; 007import java.io.IOException; 008import java.io.InputStream; 009import java.io.InputStreamReader; 010import java.net.HttpURLConnection; 011import java.net.URL; 012import java.nio.charset.Charset; 013import java.util.Map.Entry; 014 015import org.junit.After; 016import org.junit.AfterClass; 017import org.junit.Before; 018import org.junit.BeforeClass; 019import org.junit.Test; 020import org.mortbay.jetty.Server; 021import org.mortbay.jetty.servlet.Context; 022import org.mortbay.jetty.servlet.ServletHolder; 023 024import ca.uhn.hl7v2.AcknowledgmentCode; 025import ca.uhn.hl7v2.DefaultHapiContext; 026import ca.uhn.hl7v2.HL7Exception; 027import ca.uhn.hl7v2.hoh.api.IAuthorizationServerCallback; 028import ca.uhn.hl7v2.hoh.api.IMessageHandler; 029import ca.uhn.hl7v2.hoh.api.IReceivable; 030import ca.uhn.hl7v2.hoh.api.IResponseSendable; 031import ca.uhn.hl7v2.hoh.api.MessageProcessingException; 032import ca.uhn.hl7v2.hoh.encoder.EncodingStyle; 033import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestEncoder; 034import ca.uhn.hl7v2.hoh.llp.Hl7OverHttpLowerLayerProtocol; 035import ca.uhn.hl7v2.hoh.raw.api.RawSendable; 036import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider; 037import ca.uhn.hl7v2.hoh.util.ServerRoleEnum; 038import ca.uhn.hl7v2.hoh.util.StringUtils; 039import ca.uhn.hl7v2.model.v25.message.ADT_A05; 040import ca.uhn.hl7v2.parser.DefaultXMLParser; 041import ca.uhn.hl7v2.parser.EncodingNotSupportedException; 042import ca.uhn.hl7v2.parser.GenericParser; 043 044public class HohRawServletTest implements IAuthorizationServerCallback, IMessageHandler<String> { 045 046 private static DefaultHapiContext ourHapiContext; 047 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawServletTest.class); 048 private String myExpectedPassword; 049 private String myExpectedUri; 050 private String myExpectedUsername; 051 private String myMessage; 052 private String myResponse; 053 private int myPort; 054 private Server myServer; 055 056 @After 057 public void after() throws Exception { 058 myServer.stop(); 059 } 060 061 public boolean authorize(String theUri, String theUsername, String thePassword) { 062 if (myExpectedUsername == null) { 063 return true; 064 } else { 065 if (!StringUtils.equals(myExpectedUri, theUri)) { 066 return false; 067 } 068 if (!StringUtils.equals(myExpectedUsername, theUsername)) { 069 return false; 070 } 071 if (!StringUtils.equals(myExpectedPassword, thePassword)) { 072 return false; 073 } 074 return true; 075 } 076 077 } 078 079 @Before 080 public void before() throws Exception { 081 myPort = RandomServerPortProvider.findFreePort(); 082 myServer = new Server(myPort); 083 Context context = new Context(myServer, "/", Context.SESSIONS); 084 HohRawServlet servlet = new HohRawServlet(); 085 servlet.setAuthorizationCallback(this); 086 servlet.setMessageHandler(this); 087 context.addServlet(new ServletHolder(servlet), "/*"); 088 089 myServer.start(); 090 091 while (myServer.isStarting()) { 092 ourLog.info("Waiting for server to start..."); 093 Thread.sleep(100); 094 } 095 096 myResponse = null; 097 } 098 099 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}