Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/3.x' into 3.1
Browse files Browse the repository at this point in the history
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
  • Loading branch information
senivam committed Sep 7, 2022
2 parents 58c5f0e + 4a80068 commit a4d03e6
Show file tree
Hide file tree
Showing 23 changed files with 332 additions and 136 deletions.

This file was deleted.

13 changes: 13 additions & 0 deletions connectors/jetty-connector/pom.xml
Expand Up @@ -98,6 +98,19 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<instructions>
<Import-Package>
${jetty.osgi.version},
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
Expand Up @@ -85,6 +85,24 @@ private JettyClientProperties() {
public static final String SYNC_LISTENER_RESPONSE_MAX_SIZE =
"jersey.config.jetty.client.syncListenerResponseMaxSize";

/**
* Total timeout interval for request/response conversation, in milliseconds.
* Opposed to {@link org.glassfish.jersey.client.ClientProperties#READ_TIMEOUT}.
* <p>
* The value MUST be an instance convertible to {@link java.lang.Integer}. The
* value of zero (0) is equivalent to an interval of infinity.
* </p>
* <p>
* The default value is zero (infinity).
* </p>
* <p>
* The name of the configuration property is <tt>{@value}</tt>.
* </p>
*
* @since 2.37
*/
public static final String TOTAL_TIMEOUT = "jersey.config.jetty.client.totalTimeout";

/**
* Get the value of the specified property.
*
Expand Down
Expand Up @@ -323,8 +323,14 @@ private Request translateRequest(final ClientRequest clientRequest) {
request.followRedirects(clientRequest.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, true));
final Object readTimeout = clientRequest.resolveProperty(ClientProperties.READ_TIMEOUT, -1);
if (readTimeout != null && readTimeout instanceof Integer && (Integer) readTimeout > 0) {
request.timeout((Integer) readTimeout, TimeUnit.MILLISECONDS);
request.idleTimeout((Integer) readTimeout, TimeUnit.MILLISECONDS);
}

final Object totalTimeout = clientRequest.resolveProperty(JettyClientProperties.TOTAL_TIMEOUT, -1);
if (totalTimeout != null && totalTimeout instanceof Integer && (Integer) totalTimeout > 0) {
request.timeout((Integer) totalTimeout, TimeUnit.MILLISECONDS);
}

return request;
}

Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2022 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -16,30 +16,37 @@

package org.glassfish.jersey.jetty.connector;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;

import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.ProcessingException;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.StreamingOutput;

import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;

import org.junit.Test;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

/**
* @author Martin Matula
Expand All @@ -65,6 +72,48 @@ public String getTimeout() {
}
return "GET";
}

/**
* Long-running streaming request
*
* @param count number of packets send
* @param pauseMillis pause between each packets
*/
@GET
@Path("stream")
public Response streamsWithDelay(@QueryParam("start") @DefaultValue("0") int startMillis, @QueryParam("count") int count,
@QueryParam("pauseMillis") int pauseMillis) {
StreamingOutput streamingOutput = streamSlowly(startMillis, count, pauseMillis);

return Response.ok(streamingOutput)
.build();
}
}

private static StreamingOutput streamSlowly(int startMillis, int count, int pauseMillis) {

return output -> {
try {
TimeUnit.MILLISECONDS.sleep(startMillis);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
output.write("begin\n".getBytes(StandardCharsets.UTF_8));
output.flush();
for (int i = 0; i < count; i++) {
try {
TimeUnit.MILLISECONDS.sleep(pauseMillis);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

output.write(("message " + i + "\n").getBytes(StandardCharsets.UTF_8));
output.flush();
}
output.write("end".getBytes(StandardCharsets.UTF_8));
};
}

@Override
Expand Down Expand Up @@ -121,4 +170,74 @@ public void testTimeoutInRequest() {
c.close();
}
}

/**
* Test accessing an operation that is streaming slowly
*
* @throws ProcessingException in case of a test error.
*/
@Test
public void testSlowlyStreamedContentDoesNotReadTimeout() throws Exception {

int count = 5;
int pauseMillis = 50;

final Response response = target("test")
.property(ClientProperties.READ_TIMEOUT, 100L)
.property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
.path("stream")
.queryParam("count", count)
.queryParam("pauseMillis", pauseMillis)
.request().get();

assertTrue(response.readEntity(String.class).contains("end"));
}

@Test
public void testSlowlyStreamedContentDoesTotalTimeout() throws Exception {

int count = 5;
int pauseMillis = 50;

try {
target("test")
.property(JettyClientProperties.TOTAL_TIMEOUT, 100L)
.property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
.path("stream")
.queryParam("count", count)
.queryParam("pauseMillis", pauseMillis)
.request().get();

fail("This operation should trigger total timeout");
} catch (ProcessingException e) {
assertEquals(TimeoutException.class, e.getCause().getClass());
}
}

/**
* Test accessing an operation that is streaming slowly
*
* @throws ProcessingException in case of a test error.
*/
@Test
public void testSlowToStartStreamedContentDoesReadTimeout() throws Exception {

int start = 150;
int count = 5;
int pauseMillis = 50;

try {
target("test")
.property(ClientProperties.READ_TIMEOUT, 100L)
.property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER_SERVER, "-1")
.path("stream")
.queryParam("start", start)
.queryParam("count", count)
.queryParam("pauseMillis", pauseMillis)
.request().get();
fail("This operation should trigger idle timeout");
} catch (ProcessingException e) {
assertEquals(TimeoutException.class, e.getCause().getClass());
}
}
}
5 changes: 5 additions & 0 deletions connectors/netty-connector/pom.xml
Expand Up @@ -67,6 +67,11 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
</plugin>
</plugins>
</build>

Expand Down
8 changes: 8 additions & 0 deletions containers/jetty-http/pom.xml
Expand Up @@ -84,6 +84,14 @@
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<instructions>
<Import-Package>
${jetty.osgi.version},
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>

Expand Down
1 change: 1 addition & 0 deletions containers/jetty-servlet/pom.xml
Expand Up @@ -74,6 +74,7 @@
<instructions>
<Import-Package>
jakarta.servlet.*;version="[5.0,7.0)",
${jetty.osgi.version},
*
</Import-Package>
</instructions>
Expand Down
17 changes: 17 additions & 0 deletions docs/src/main/docbook/appendix-properties.xml
Expand Up @@ -1897,6 +1897,23 @@
</para>
</entry>
</row>
<row>
<entry>&jersey.jetty.JettyClientProperties.TOTAL_TIMEOUT;</entry>
<entry><literal>jersey.config.jetty.client.totalTimeout</literal></entry>
<entry>
<para>
Total timeout interval for request/response conversation, in milliseconds.
Opposed to &jersey.client.ClientProperties.READ_TIMEOUT;.
</para>
<para>
The value MUST be an instance convertible to <literal>Integer</literal>.
The value of zero <literal>0</literal> is equivalent to an interval of infinity.
</para>
<para>
The default value is <literal>0</literal> (infinity).
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
Expand Down
1 change: 1 addition & 0 deletions docs/src/main/docbook/jersey.ent
Expand Up @@ -477,6 +477,7 @@
<!ENTITY jersey.jetty.JettyClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#DISABLE_COOKIES'>JettyClientProperties.DISABLE_COOKIES</link>" >
<!ENTITY jersey.jetty.JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>" >
<!ENTITY jersey.jetty.JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#SYNC_LISTENER_RESPONSE_MAX_SIZE'>JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE</link>" >
<!ENTITY jersey.jetty.JettyClientProperties.TOTAL_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#TOTAL_TIMEOUT'>JettyClientProperties.TOTAL_TIMEOUT</link>" >
<!ENTITY jersey.jetty.JettyConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyConnectorProvider.html'>JettyConnectorProvider</link>">
<!ENTITY jersey.jetty.JettyHttpContainer "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainer.html'>JettyHttpContainer</link>">
<!ENTITY jersey.jetty.JettyHttpContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerFactory.html'>JettyHttpContainerFactory</link>">
Expand Down

0 comments on commit a4d03e6

Please sign in to comment.