001package ca.uhn.hl7v2.hoh.raw.client;
002
003import static org.junit.Assert.*;
004
005import org.junit.After;
006import org.junit.Before;
007import org.junit.Test;
008
009import ca.uhn.hl7v2.hoh.api.DecodeException;
010import ca.uhn.hl7v2.hoh.api.IReceivable;
011import ca.uhn.hl7v2.hoh.auth.SingleCredentialClientCallback;
012import ca.uhn.hl7v2.hoh.auth.SingleCredentialServerCallback;
013import ca.uhn.hl7v2.hoh.encoder.EncodingStyle;
014import ca.uhn.hl7v2.hoh.llp.Hl7OverHttpLowerLayerProtocol;
015import ca.uhn.hl7v2.hoh.llp.ServerSocketThreadForTesting;
016import ca.uhn.hl7v2.hoh.raw.api.RawSendable;
017import ca.uhn.hl7v2.hoh.util.RandomServerPortProvider;
018import ca.uhn.hl7v2.hoh.util.ServerRoleEnum;
019
020public class HohRawClientMultithreadedTest {
021        private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HohRawClientMultithreadedTest.class);
022        private static int myPort;
023        private static Hl7OverHttpLowerLayerProtocol myLlp;
024        private static SingleCredentialServerCallback ourServerCallback;
025        private static ServerSocketThreadForTesting myServerSocketThread;
026
027        @Test
028        public void testSendMessageSimple() throws Exception {
029
030                String message = // -
031                "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
032                                "EVN||200803051509\r" + // -
033                                "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
034
035                HohRawClientMultithreaded client = new HohRawClientMultithreaded("localhost", myPort, "/theUri");
036                client.setSocketTimeout(500);
037                
038                client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld"));
039
040                /*
041                 * Send one message
042                 */
043                ourLog.info("*** Send message #1");
044                
045                IReceivable<String> response = client.sendAndReceive(new RawSendable(message));
046                assertEquals(message, myServerSocketThread.getMessage());
047                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
048
049                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
050                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
051                assertEquals(1, myServerSocketThread.getConnectionCount());
052                
053                
054                /*
055                 * Send a second message
056                 */
057                ourLog.info("*** Send message #2");
058                
059                response = client.sendAndReceive(new RawSendable(message));
060                assertEquals(message, myServerSocketThread.getMessage());
061                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
062
063                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
064                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
065                assertEquals(1, myServerSocketThread.getConnectionCount());
066
067                Thread.sleep(1000);
068                
069                /*
070                 * Send a third message
071                 */
072                ourLog.info("*** Send message #3");
073                
074                response = client.sendAndReceive(new RawSendable(message));
075                assertEquals(message, myServerSocketThread.getMessage());
076                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
077
078                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
079                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
080                assertEquals(2, myServerSocketThread.getConnectionCount());
081
082        }
083
084        @Test
085        public void testSendMessageAndRespectCloseHeaderInResponse() throws Exception {
086
087                String message = // -
088                "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
089                                "EVN||200803051509\r" + // -
090                                "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
091
092                HohRawClientMultithreaded client = new HohRawClientMultithreaded("localhost", myPort, "/theUri");
093                client.setSocketTimeout(500);
094                
095                client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld"));
096
097                myServerSocketThread.setCloseNormallyWithHeaderAfterEachMessage();
098                
099                /*
100                 * Send one message
101                 */
102                ourLog.info("*** Send message #1");
103                
104                IReceivable<String> response = client.sendAndReceive(new RawSendable(message));
105                assertEquals(message, myServerSocketThread.getMessage());
106                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
107
108                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
109                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
110                assertEquals(1, myServerSocketThread.getConnectionCount());
111                
112                
113                /*
114                 * Send a second message
115                 */
116                ourLog.info("*** Send message #2");
117                
118                response = client.sendAndReceive(new RawSendable(message));
119                assertEquals(message, myServerSocketThread.getMessage());
120                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
121
122                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
123                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
124                assertEquals(2, myServerSocketThread.getConnectionCount());
125
126                Thread.sleep(1000);
127                
128                /*
129                 * Send a third message
130                 */
131                ourLog.info("*** Send message #3");
132                
133                response = client.sendAndReceive(new RawSendable(message));
134                assertEquals(message, myServerSocketThread.getMessage());
135                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
136
137                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
138                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
139                assertEquals(3, myServerSocketThread.getConnectionCount());
140
141        }
142
143        @Test
144        public void testSendMessageWithNoTimeout() throws Exception {
145
146                String message = // -
147                "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
148                                "EVN||200803051509\r" + // -
149                                "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
150
151                HohRawClientMultithreaded client = new HohRawClientMultithreaded("localhost", myPort, "/theUri");
152                client.setSocketTimeout(-1);
153                
154                client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld"));
155
156                /*
157                 * Send one message
158                 */
159                ourLog.info("*** Send message #1");
160                
161                IReceivable<String> response = client.sendAndReceive(new RawSendable(message));
162                assertEquals(message, myServerSocketThread.getMessage());
163                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
164
165                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
166                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
167                assertEquals(1, myServerSocketThread.getConnectionCount());
168                
169                Thread.sleep(1000);
170                
171                /*
172                 * Send a third message
173                 */
174                ourLog.info("*** Send message #2");
175                
176                response = client.sendAndReceive(new RawSendable(message));
177                assertEquals(message, myServerSocketThread.getMessage());
178                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
179
180                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
181                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
182                assertEquals(1, myServerSocketThread.getConnectionCount());
183
184        }
185
186        @Test
187        public void testReconnectAutomaticallyAfterUnexpectedClose() throws Exception {
188                myServerSocketThread.setCloseUnexpectedlyAfterEachMessage();
189                
190                String message = // -
191                "MSH|^~\\&|||||200803051508||ADT^A31|2|P|2.5\r" + // -
192                                "EVN||200803051509\r" + // -
193                                "PID|||ZZZZZZ83M64Z148R^^^SSN^SSN^^20070103\r"; // -
194
195                HohRawClientMultithreaded client = new HohRawClientMultithreaded("localhost", myPort, "/theUri");
196                client.setSocketTimeout(1000);
197                
198                client.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld"));
199
200                /*
201                 * Send one message
202                 */
203                ourLog.info("*** Send message #1");
204                
205                IReceivable<String> response = client.sendAndReceive(new RawSendable(message));
206                assertEquals(message, myServerSocketThread.getMessage());
207                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
208
209                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
210                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
211                assertEquals(1, myServerSocketThread.getConnectionCount());
212                
213                Thread.sleep(100);
214                
215                /*
216                 * Send a third message
217                 */
218                ourLog.info("*** Send message #2");
219                
220                try {
221                        response = client.sendAndReceive(new RawSendable(message));
222                } catch (Exception e) {
223                        // We're allowed to fail once
224                }
225                
226                // This try should succeed again
227                response = client.sendAndReceive(new RawSendable(message));
228                assertEquals(message, myServerSocketThread.getMessage());
229                assertEquals(myServerSocketThread.getReply().encode(), response.getMessage());
230
231                assertEquals(EncodingStyle.ER7.getContentType(), myServerSocketThread.getContentType());
232                assertEquals(EncodingStyle.ER7, myServerSocketThread.getEncoding());
233                assertEquals(2, myServerSocketThread.getConnectionCount());
234
235        }
236        @After
237        public void after() throws InterruptedException {
238                ourLog.info("Marking done as true");
239                myServerSocketThread.done();
240        }
241
242        @Before
243        public void before() throws InterruptedException {
244                myPort = RandomServerPortProvider.findFreePort();
245
246                myLlp = new Hl7OverHttpLowerLayerProtocol(ServerRoleEnum.CLIENT);
247                myLlp.setAuthorizationCallback(new SingleCredentialClientCallback("hello", "hapiworld"));
248                ourServerCallback = new SingleCredentialServerCallback("hello", "hapiworld");
249
250                myServerSocketThread = new ServerSocketThreadForTesting(myPort, ourServerCallback);
251                myServerSocketThread.start();
252                myServerSocketThread.getLatch().await();
253        }
254
255}