001package ca.uhn.hl7v2.hoh.llp; 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; 014import java.util.Map.Entry; 015 016import ca.uhn.hl7v2.protocol.ReceivingApplication; 017import ca.uhn.hl7v2.protocol.ReceivingApplicationException; 018import org.junit.After; 019import org.junit.Before; 020import org.junit.Test; 021 022import ca.uhn.hl7v2.AcknowledgmentCode; 023import ca.uhn.hl7v2.HL7Exception; 024import ca.uhn.hl7v2.app.Application; 025import ca.uhn.hl7v2.app.ApplicationException; 026import ca.uhn.hl7v2.app.Connection; 027import ca.uhn.hl7v2.app.ConnectionListener; 028import ca.uhn.hl7v2.app.SimpleServer; 029import ca.uhn.hl7v2.hoh.encoder.EncodingStyle; 030import ca.uhn.hl7v2.hoh.encoder.Hl7OverHttpRequestEncoder; 031import ca.uhn.hl7v2.hoh.sign.BouncyCastleCmsMessageSignerTest; 032import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider; 033import ca.uhn.hl7v2.hoh.util.ServerRoleEnum; 034import ca.uhn.hl7v2.model.Message; 035import ca.uhn.hl7v2.parser.DefaultXMLParser; 036import ca.uhn.hl7v2.parser.GenericParser; 037import ca.uhn.hl7v2.parser.PipeParser; 038 039public class LlpServerTest implements ReceivingApplication<Message>, ConnectionListener { 040 041 private int myPort; 042 private Hl7OverHttpLowerLayerProtocol myLlp; 043 private SimpleServer myServer; 044 private Message myMessage; 045 private int myConnections; 046 private Message myResponse; 047 048 @Before 049 public void before() throws InterruptedException { 050 myPort = RandomServerPortProvider.findFreePort(); 051 052 myLlp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.SERVER); 053 myServer = new SimpleServer(myPort, myLlp, GenericParser.getInstanceWithNoValidation()); 054 myServer.registerApplication("*", "*", this); 055 myServer.registerConnectionListener(this); 056 myMessage = (Message) null; 057 myResponse = (Message) null; 058 myConnections = 0; 059 } 060 061 @Test 062 public void testSendSimple() throws Exception { 063 myServer.startAndWait(); 064 065 String message = // - 066 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 067 "EVN||200803051509\r" + // - 068 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 069 070 Hl7OverHttpRequestEncoder enc = new Hl7OverHttpRequestEncoder(); 071 String charsetName = "ISO-8859-2"; 072 enc.setCharset(Charset.forName(charsetName)); 073 enc.setUsername("hello"); 074 enc.setPassword("world"); 075 enc.setMessage(message); 076 enc.encode(); 077 078 String urlString = "http://localhost:" + myPort + "/"; 079 ourLog.info("URL: {}", urlString); 080 URL url = new URL(urlString); 081 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 082 conn.setRequestMethod("POST"); 083 084 conn.setUseCaches(false); 085 conn.setDoInput(true); 086 conn.setDoOutput(true); 087 for (Entry<String, String> next : enc.getHeaders().entrySet()) { 088 conn.setRequestProperty(next.getKey(), next.getValue()); 089 } 090 091 DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); 092 wr.write(enc.getData()); 093 wr.flush(); 094 095 // Get Response 096 InputStream is = conn.getInputStream(); 097 BufferedReader rd = new BufferedReader(new InputStreamReader(is)); 098 String line; 099 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}