Skip to content

Commit b752f73

Browse files
authored
Http client connection issue (#356)
* Troubleshooting occasional connection issues * Troubleshooting occasional connection issues * Changed nginx container wait strategy
1 parent d47ee37 commit b752f73

File tree

3 files changed

+35
-35
lines changed

3 files changed

+35
-35
lines changed

tests/src/org.apache.httpcomponents/httpclient/4.5.14/.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,3 @@ gradlew.bat
22
gradlew
33
gradle/
44
build/
5-
nginx-stderr.txt
6-
nginx-stdout.txt

tests/src/org.apache.httpcomponents/httpclient/4.5.14/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,11 @@ dependencies {
1515
testImplementation "org.apache.httpcomponents:httpclient:$libraryVersion"
1616
testImplementation 'org.assertj:assertj-core:3.22.0'
1717
}
18+
19+
graalvmNative {
20+
binaries {
21+
test {
22+
buildArgs.add('--enable-url-protocols=http')
23+
}
24+
}
25+
}

tests/src/org.apache.httpcomponents/httpclient/4.5.14/src/test/java/org_apache_httpcomponents/httpclient/HttpClientTest.java

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@
1919
import org.junit.jupiter.api.BeforeAll;
2020
import org.junit.jupiter.api.Test;
2121

22-
import java.io.File;
2322
import java.io.IOException;
24-
import java.net.InetSocketAddress;
23+
import java.net.HttpURLConnection;
2524
import java.net.ServerSocket;
26-
import java.net.Socket;
27-
import java.net.SocketTimeoutException;
25+
import java.net.URL;
26+
import java.util.concurrent.Callable;
2827

2928
import static org.assertj.core.api.Assertions.assertThat;
3029

3130
class HttpClientTest {
3231

3332
private static int port;
3433

34+
private static String uri;
35+
3536
private static Process process;
3637

3738
@BeforeAll
@@ -40,15 +41,16 @@ static void beforeAll() throws IOException {
4041
port = findAvailablePort();
4142
System.out.println("Found port: " + port);
4243

44+
uri = "http://localhost:%d/".formatted(port);
45+
4346
System.out.println("Starting nginx ...");
4447
process = new ProcessBuilder(
4548
"docker", "run", "--rm", "-p", port + ":80", "nginx:1-alpine-slim")
46-
.redirectOutput(new File("nginx-stdout.txt"))
47-
.redirectError(new File("nginx-stderr.txt"))
49+
.inheritIO()
4850
.start();
4951

5052
// Wait until connection can be established
51-
waitUntilContainerStarted(60);
53+
waitUntil(() -> openConnection(uri), 60, 1);
5254

5355
System.out.println("nginx started");
5456
}
@@ -62,42 +64,34 @@ private static int findAvailablePort() throws IOException {
6264
}
6365
}
6466

65-
private static void waitUntilContainerStarted(int startupTimeoutSeconds) {
66-
System.out.println("Waiting for nginx container to become available");
67+
private static boolean openConnection(String uri) throws Exception {
68+
HttpURLConnection connection = (HttpURLConnection) new URL(uri).openConnection();
69+
connection.setReadTimeout(1000);
70+
connection.setRequestMethod("GET");
71+
connection.connect();
72+
return HttpURLConnection.HTTP_OK == connection.getResponseCode();
73+
}
6774

68-
Exception lastConnectionException = null;
75+
private static void waitUntil(Callable<Boolean> conditionEvaluator, int timeoutSeconds, int sleepTimeSeconds) {
76+
Exception lastException = null;
6977

70-
long end = System.currentTimeMillis() + startupTimeoutSeconds * 1000L;
78+
long end = System.currentTimeMillis() + timeoutSeconds * 1000L;
7179
while (System.currentTimeMillis() < end) {
7280
try {
73-
Thread.sleep(100L);
81+
Thread.sleep(sleepTimeSeconds * 1000L);
7482
} catch (InterruptedException e) {
7583
// continue
7684
}
77-
try (Socket socket = new Socket()) {
78-
socket.setSoTimeout(100);
79-
socket.connect(new InetSocketAddress("localhost", port), 100);
80-
if (!check(socket)) {
81-
continue;
85+
try {
86+
if (conditionEvaluator.call()) {
87+
return;
8288
}
83-
return;
8489
} catch (Exception e) {
85-
lastConnectionException = e;
86-
}
87-
}
88-
throw new IllegalStateException("nginx container cannot be accessed on localhost:" + port, lastConnectionException);
89-
}
90-
91-
private static boolean check(Socket socket) throws IOException {
92-
try {
93-
// -1 indicates the socket has been closed immediately
94-
// Other responses or a timeout are considered as success
95-
if (socket.getInputStream().read() == -1) {
96-
return false;
90+
lastException = e;
9791
}
98-
} catch (SocketTimeoutException ex) {
9992
}
100-
return true;
93+
String errorMessage = "Condition was not fulfilled within " + timeoutSeconds + " seconds";
94+
throw lastException == null ? new IllegalStateException(errorMessage) : new IllegalStateException(errorMessage, lastException);
10195
}
10296

10397
@AfterAll
@@ -116,7 +110,7 @@ void testBasicSchemeDeserialization() throws Exception {
116110
HttpClientContext context = HttpClientContext.create();
117111
context.setAuthCache(authCache);
118112

119-
HttpGet httpGet = new HttpGet("http://localhost:%d/".formatted(port));
113+
HttpGet httpGet = new HttpGet(uri);
120114
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
121115
try (CloseableHttpResponse response = httpclient.execute(httpGet, context)) {
122116
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);

0 commit comments

Comments
 (0)