001package ca.uhn.hl7v2.hoh.raw.client; 002 003import static org.junit.Assert.assertEquals; 004import static org.junit.Assert.assertTrue; 005 006import java.net.MalformedURLException; 007import java.net.URL; 008 009import org.apache.log4j.Level; 010import org.apache.log4j.LogManager; 011import org.junit.After; 012import org.junit.Before; 013import org.junit.Test; 014 015import ca.uhn.hl7v2.hoh.api.IReceivable; 016import ca.uhn.hl7v2.hoh.auth.SingleCredentialClientCallback; 017import ca.uhn.hl7v2.hoh.auth.SingleCredentialServerCallback; 018import ca.uhn.hl7v2.hoh.encoder.EncodingStyle; 019import ca.uhn.hl7v2.hoh.llp.Hl7OverHttpLowerLayerProtocol; 020import ca.uhn.hl7v2.hoh.llp.ServerSocketThreadForTesting; 021import ca.uhn.hl7v2.hoh.raw.api.RawSendable; 022import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider; 023import ca.uhn.hl7v2.hoh.util.ServerRoleEnum; 024import ca.uhn.hl7v2.parser.DefaultXMLParser; 025import ca.uhn.hl7v2.parser.PipeParser; 026 027public class HohRawClientSimpleTest { 028 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawClientSimpleTest.class); 029 private static int myPort; 030 private static Hl7OverHttpLowerLayerProtocol myLlp; 031 private static SingleCredentialServerCallback ourServerCallback; 032 private static ServerSocketThreadForTesting myServerSocketThread; 033 private Level myExistingLogLevel; 034 035 036 @Test 037 public void testSendMessageSimple() throws Exception { 038 LogManager.getRootLogger().setLevel((Level)Level.TRACE); 039 040 String message = // - 041 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 042 "EVN||200803051509\r" + // - 043 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 044 045 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 046 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 047 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 048 049 ourLog.info("Received response"); 050 051 assertEquals(message, myServerSocketThread.getMessage()); 052 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 053 054 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 055 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 056 057 } 058 059 060 @Test 061 public void testSendMessageAndRespectCloseHeaderInResponse() throws Exception { 062 063 String message = // - 064 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 065 "EVN||200803051509\r" + // - 066 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 067 068 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 069 070 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 071 072 myServerSocketThread.setCloseNormallyWithHeaderAfterEachMessage(); 073 074 /* 075 * Send one message 076 */ 077 ourLog.info("*** Send message #1"); 078 079 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 080 assertEquals(message, myServerSocketThread.getMessage()); 081 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 082 083 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 084 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 085 assertEquals(1, myServerSocketThread.getConnectionCount()); 086 087 088 /* 089 * Send a second message 090 */ 091 ourLog.info("*** Send message #2"); 092 093 response = client.sendAndReceive(new RawSendable(message)); 094 assertEquals(message, myServerSocketThread.getMessage()); 095 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 096 097 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 098 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 099 assertEquals(2, myServerSocketThread.getConnectionCount()); 100 101 Thread.sleep(1000); 102 103 /* 104 * Send a third message 105 */ 106 ourLog.info("*** Send message #3"); 107 108 response = client.sendAndReceive(new RawSendable(message)); 109 assertEquals(message, myServerSocketThread.getMessage()); 110 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 111 112 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 113 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 114 assertEquals(3, myServerSocketThread.getConnectionCount()); 115 116 } 117 118 @Test 119 public void testUnderstandsGzippedResponse() throws Exception { 120 LogManager.getRootLogger().setLevel((Level)Level.TRACE); 121 122 myServerSocketThread.setGZipResponse(true); 123 124 String message = // - 125 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 126 "EVN||200803051509\r" + // - 127 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 128 129 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 130 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 131 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 132 133 ourLog.info("Received response"); 134 135 assertEquals(message, myServerSocketThread.getMessage()); 136 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 137 138 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 139 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 140 141 } 142 143 144 @Test(expected = IllegalArgumentException.class) 145 public void testInvalidUriRejected1() throws Exception { 146 new HohRawClientSimple("localhost", 9999, "/uri space"); 147 } 148 149 @Test(expected = IllegalArgumentException.class) 150 public void testInvalidUriRejected2() throws Exception { 151 new HohRawClientSimple("localhost", 9999, "uri_with_no_starting_slash"); 152 } 153 154 @Test(expected = IllegalArgumentException.class) 155 public void testInvalidUriRejected3() throws Exception { 156 new HohRawClientSimple("localhost", 9999, "/uri_with_%_bad_char"); 157 } 158 159 // TODO: add test with chunked encoding and additional trailing headers 160 161 /** 162 * Ensure that if chunked transfer encoding is used, and there is a pause in 163 * the middle of transmission, the whole message is still read 164 */ 165 @Test 166 public void testSendMessageWithChunkedResponseAndPauseInMiddle() throws Exception { 167 168 myServerSocketThread.setSimulateOneSecondPauseInChunkedEncoding(true); 169 170 String message = // - 171 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 172 "EVN||200803051509\r" + // - 173 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 174 175 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 176 client.setSoTimeout(500); 177 client.setResponseTimeout(2000); 178 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 179 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 180 181 ourLog.info("Received response"); 182 183 assertEquals(message, myServerSocketThread.getMessage()); 184 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 185 186 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 187 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 188 189 } 190 191 /** 192 * Ensure that if chunked transfer encoding is used, and there is a pause in 193 * the middle of transmission, the whole message is still read 194 */ 195 @Test 196 public void testSendMessageWithChunkedResponseAndPauseInMiddleWithLongSoTimeout() throws Exception { 197 198 myServerSocketThread.setSimulateOneSecondPauseInChunkedEncoding(true); 199 200 String message = // - 201 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 202 "EVN||200803051509|||||||||||||||||||||||||||||||||||||||||\r" + // - 203 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 204 205 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 206 client.setSoTimeout(980); 207 client.setKeepAlive(false); 208 client.setResponseTimeout(2000); 209 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 210 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 211 212 ourLog.info("Received response"); 213 214 assertEquals(message, myServerSocketThread.getMessage()); 215 assertEquals(myServerSocketThread.getReply().encode(), response.getMessage()); 216 217 assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType()); 218 assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding()); 219 220 } 221 222 @Test 223 public void testSendMessageSimpleXml() throws Exception { 224 225 String message = // - 226 "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // - 227 "EVN||200803051509\r" + // - 228 "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // - 229 message = new DefaultXMLParser().encode(PipeParser.getInstanceWithNoValidation().parse(message)); 230 231 HohRawClientSimple client = new HohRawClientSimple("localhost", myPort, "/theUri"); 232 client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 233 IReceivable<String> response = client.sendAndReceive(new RawSendable(message)); 234 235 ourLog.info("Received response"); 236 237 assertEquals(message, myServerSocketThread.getMessage()); 238 String responseMessage = response.getMessage(); 239 assertTrue(responseMessage, responseMessage.contains("<MSH>")); 240 assertEquals(myServerSocketThread.getReply().encode(), responseMessage); 241 242 assertEquals(EncodingStyle.XML.getContentType(), myServerSocketThread.getContentType()); 243 assertEquals(EncodingStyle.XML, myServerSocketThread.getEncoding()); 244 } 245 246 @Test 247 public void testCreateUsingUrl() throws MalformedURLException { 248 249 HohRawClientSimple c = new HohRawClientSimple(new URL("http://somehost/")); 250 assertEquals("somehost", c.getHost()); 251 assertEquals("/", c.getUriPath()); 252 assertEquals(80, c.getPort()); 253 254 c = new HohRawClientSimple(new URL("http://somehost:8888/")); 255 assertEquals("somehost", c.getHost()); 256 assertEquals("/", c.getUriPath()); 257 assertEquals(8888, c.getPort()); 258 259 c = new HohRawClientSimple(new URL("http://somehost:8888/someuri/path/test.jsp")); 260 assertEquals("somehost", c.getHost()); 261 assertEquals("/someuri/path/test.jsp", c.getUriPath()); 262 assertEquals(8888, c.getPort()); 263 264 c = new HohRawClientSimple(new URL("https://somehost/someuri/path/test.jsp")); 265 assertEquals("somehost", c.getHost()); 266 assertEquals("/someuri/path/test.jsp", c.getUriPath()); 267 assertEquals(443, c.getPort()); 268 269 } 270 271 @After 272 public void after() throws InterruptedException { 273 ourLog.info("Marking done as true"); 274 myServerSocketThread.done(); 275 276 // Restore the log level 277 LogManager.getRootLogger().setLevel(myExistingLogLevel); 278 } 279 280 @Before 281 public void before() throws InterruptedException { 282 myExistingLogLevel = LogManager.getRootLogger().getLevel(); 283 284 myPort = RandomServerPortProvider.findFreePort(); 285 286 myLlp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT); 287 myLlp.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld")); 288 ourServerCallback = new SingleCredentialServerCallback("hello", "hapiworld"); 289 290 myServerSocketThread = new ServerSocketThreadForTesting(myPort, ourServerCallback); 291 myServerSocketThread.start(); 292 myServerSocketThread.getLatch().await(); 293 } 294 295 296 297 298}