Skip to content

Commit 2e777bc

Browse files
Implement custom http request timeout executor
LMCROSSITXSADEPLOY-2910
1 parent ea0d446 commit 2e777bc

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.cloudfoundry.multiapps.controller.core.http;
2+
3+
import java.io.IOException;
4+
import java.util.Timer;
5+
import java.util.TimerTask;
6+
import java.util.function.Function;
7+
import org.apache.http.HttpResponse;
8+
import org.apache.http.client.HttpClient;
9+
import org.apache.http.client.methods.HttpUriRequest;
10+
import org.cloudfoundry.multiapps.common.SLException;
11+
12+
public class TimeoutHttpExecutor {
13+
14+
private final HttpClient client;
15+
16+
public TimeoutHttpExecutor(HttpClient client) {
17+
this.client = client;
18+
}
19+
20+
public <T> T executeWithTimeout(HttpUriRequest request, long timeoutInMillis, Function<HttpResponse, T> responseHandler) {
21+
TimerTask task = buildAbortRequestTimerTask(request);
22+
Timer timer = new Timer(true);
23+
timer.schedule(task, timeoutInMillis);
24+
try {
25+
final HttpResponse response = client.execute(request);
26+
return responseHandler.apply(response);
27+
} catch (IOException e) {
28+
throw new SLException(e, e.getMessage());
29+
} finally {
30+
task.cancel();
31+
timer.cancel();
32+
}
33+
}
34+
35+
private TimerTask buildAbortRequestTimerTask(HttpUriRequest request) {
36+
return new TimerTask() {
37+
@Override
38+
public void run() {
39+
if (!request.isAborted()) {
40+
request.abort();
41+
}
42+
}
43+
};
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.cloudfoundry.multiapps.controller.core.http;
2+
3+
import java.io.IOException;
4+
import java.util.function.Function;
5+
import org.apache.http.HttpResponse;
6+
import org.apache.http.client.HttpClient;
7+
import org.apache.http.client.methods.HttpUriRequest;
8+
import org.cloudfoundry.multiapps.common.SLException;
9+
import org.junit.jupiter.api.BeforeEach;
10+
import org.junit.jupiter.api.Test;
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
import static org.junit.jupiter.api.Assertions.assertThrows;
13+
import static org.mockito.Mockito.mock;
14+
import static org.mockito.Mockito.never;
15+
import static org.mockito.Mockito.times;
16+
import static org.mockito.Mockito.verify;
17+
import static org.mockito.Mockito.when;
18+
19+
class TimeoutHttpExecutorTest {
20+
21+
private HttpClient mockHttpClient;
22+
private HttpUriRequest mockRequest;
23+
private HttpResponse mockResponse;
24+
private TimeoutHttpExecutor timeoutHttpExecutor;
25+
26+
@BeforeEach
27+
void setUp() {
28+
mockHttpClient = mock(HttpClient.class);
29+
mockRequest = mock(HttpUriRequest.class);
30+
mockResponse = mock(HttpResponse.class);
31+
timeoutHttpExecutor = new TimeoutHttpExecutor(mockHttpClient);
32+
}
33+
34+
@Test
35+
void testExecuteWithTimeoutSuccessfulExecution() throws IOException {
36+
when(mockHttpClient.execute(mockRequest)).thenReturn(mockResponse);
37+
Function<HttpResponse, String> responseHandler = response -> "Success";
38+
39+
String result = timeoutHttpExecutor.executeWithTimeout(mockRequest, 1000, responseHandler);
40+
41+
assertEquals("Success", result);
42+
verify(mockHttpClient, times(1)).execute(mockRequest);
43+
verify(mockRequest, never()).abort();
44+
}
45+
46+
@Test
47+
void testExecuteWithTimeoutRequestAbortedDueToTimeout() throws IOException {
48+
when(mockHttpClient.execute(mockRequest)).thenAnswer(invocation -> {
49+
Thread.sleep(200); // Simulate a delay
50+
return mockResponse;
51+
});
52+
Function<HttpResponse, String> responseHandler = response -> "Success";
53+
54+
timeoutHttpExecutor.executeWithTimeout(mockRequest, 100, responseHandler);
55+
verify(mockRequest, times(1)).abort();
56+
}
57+
58+
@Test
59+
void testExecuteWithTimeoutIOExceptionThrown() throws IOException {
60+
when(mockHttpClient.execute(mockRequest)).thenThrow(new IOException("Connection error"));
61+
Function<HttpResponse, String> responseHandler = response -> "Success";
62+
63+
SLException exception = assertThrows(SLException.class,
64+
() -> timeoutHttpExecutor.executeWithTimeout(mockRequest, 1000, responseHandler));
65+
assertEquals("Connection error", exception.getMessage());
66+
verify(mockRequest, never()).abort();
67+
}
68+
69+
}

0 commit comments

Comments
 (0)