2525import javax .ws .rs .client .WebTarget ;
2626import javax .ws .rs .core .Application ;
2727import javax .ws .rs .core .MediaType ;
28-
28+ import javax . ws . rs . core . Response ;
2929import javax .inject .Singleton ;
3030
31+ import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
32+
3133import org .glassfish .jersey .client .ClientConfig ;
34+ import org .glassfish .jersey .client .ClientProperties ;
3235import org .glassfish .jersey .server .ChunkedOutput ;
3336import org .glassfish .jersey .server .ResourceConfig ;
3437import org .glassfish .jersey .test .JerseyTest ;
4043 * @author Petr Janouch (petr.janouch at oracle.com)
4144 */
4245public class StreamingTest extends JerseyTest {
46+ private PoolingHttpClientConnectionManager connectionManager ;
4347
4448 /**
4549 * Test that a data stream can be terminated from the client side.
4650 */
4751 @ Test
4852 public void clientCloseTest () throws IOException {
4953 // start streaming
50- InputStream inputStream = target ().path ("/streamingEndpoint" ).request ().get (InputStream .class );
54+ InputStream inputStream = target ().path ("/streamingEndpoint" ).request ()
55+ .property (ClientProperties .READ_TIMEOUT , 1_000 ).get (InputStream .class );
5156
5257 WebTarget sendTarget = target ().path ("/streamingEndpoint/send" );
5358 // trigger sending 'A' to the stream; OK is sent if everything on the server was OK
@@ -61,8 +66,35 @@ public void clientCloseTest() throws IOException {
6166 assertEquals ("NOK" , sendTarget .request ().get ().readEntity (String .class ));
6267 }
6368
69+ /**
70+ * Tests that closing a response after completely reading the entity reuses the connection
71+ */
72+ @ Test
73+ public void reuseConnectionTest () throws IOException {
74+ Response response = target ().path ("/streamingEndpoint/get" ).request ().get ();
75+ InputStream is = response .readEntity (InputStream .class );
76+ byte [] buf = new byte [8192 ];
77+ is .read (buf );
78+ is .close ();
79+ response .close ();
80+
81+ assertEquals (1 , connectionManager .getTotalStats ().getAvailable ());
82+ assertEquals (0 , connectionManager .getTotalStats ().getLeased ());
83+ }
84+
85+ /**
86+ * Tests that closing a request without reading the entity does not throw an exception.
87+ */
88+ @ Test
89+ public void clientCloseThrowsNoExceptionTest () throws IOException {
90+ Response response = target ().path ("/streamingEndpoint/get" ).request ().get ();
91+ response .close ();
92+ }
93+
6494 @ Override
6595 protected void configureClient (ClientConfig config ) {
96+ connectionManager = new PoolingHttpClientConnectionManager ();
97+ config .property (ApacheClientProperties .CONNECTION_MANAGER , connectionManager );
6698 config .connectorProvider (new ApacheConnectorProvider ());
6799 }
68100
@@ -94,5 +126,12 @@ public String sendEvent() {
94126 public ChunkedOutput <String > get () {
95127 return output ;
96128 }
129+
130+ @ GET
131+ @ Path ("get" )
132+ @ Produces (MediaType .TEXT_PLAIN )
133+ public String getString () {
134+ return "OK" ;
135+ }
97136 }
98137}
0 commit comments