Skip to content

Commit e688c84

Browse files
authored
[DE-411] http retries (#468)
* CodeQL fixes * added http retries for safe methods
1 parent 588edbd commit e688c84

File tree

8 files changed

+243
-139
lines changed

8 files changed

+243
-139
lines changed

.github/workflows/codeql.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ jobs:
2828
analyze:
2929
name: Analyze
3030
runs-on: ubuntu-latest
31+
32+
defaults:
33+
run:
34+
working-directory: driver
35+
3136
permissions:
3237
actions: read
3338
contents: read

driver/src/main/java/com/arangodb/internal/http/HttpCommunication.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import com.arangodb.ArangoDBException;
2424
import com.arangodb.Request;
25+
import com.arangodb.RequestType;
2526
import com.arangodb.Response;
2627
import com.arangodb.internal.net.*;
2728
import com.arangodb.internal.serde.InternalSerde;
@@ -84,8 +85,6 @@ private Response execute(final Request request, final HostHandle hostHandle, fin
8485
return response;
8586
} catch (final SocketTimeoutException e) {
8687
// SocketTimeoutException exceptions are wrapped and rethrown.
87-
// Differently from other IOException exceptions they must not be retried,
88-
// since the requests could not be idempotent.
8988
TimeoutException te = new TimeoutException(e.getMessage());
9089
te.initCause(e);
9190
throw new ArangoDBException(te, reqId);
@@ -96,7 +95,7 @@ private Response execute(final Request request, final HostHandle hostHandle, fin
9695
}
9796
final Host failedHost = host;
9897
host = hostHandler.get(hostHandle, accessType);
99-
if (host != null) {
98+
if (host != null && isSafe(request)) {
10099
LOGGER.warn("Could not connect to {} while executing request [id={}]",
101100
failedHost.getDescription(), reqId, e);
102101
LOGGER.debug("Try connecting to {}", host.getDescription());
@@ -106,9 +105,9 @@ private Response execute(final Request request, final HostHandle hostHandle, fin
106105
}
107106
}
108107
}
109-
} catch (final ArangoDBException e) {
110-
if (e instanceof ArangoDBRedirectException && attemptCount < 3) {
111-
final String location = ((ArangoDBRedirectException) e).getLocation();
108+
} catch (final ArangoDBRedirectException e) {
109+
if (attemptCount < 3) {
110+
final String location = e.getLocation();
112111
final HostDescription redirectHost = HostUtils.createFromLocation(location);
113112
hostHandler.failIfNotMatch(redirectHost, e);
114113
return execute(request, new HostHandle().setHost(redirectHost), attemptCount + 1);
@@ -118,6 +117,11 @@ private Response execute(final Request request, final HostHandle hostHandle, fin
118117
}
119118
}
120119

120+
private boolean isSafe(final Request request) {
121+
RequestType type = request.getRequestType();
122+
return type == RequestType.GET || type == RequestType.HEAD || type == RequestType.OPTIONS;
123+
}
124+
121125
public static class Builder {
122126
private HostHandler hostHandler;
123127
private InternalSerde serde;

driver/src/main/java/com/arangodb/internal/http/HttpConnection.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import java.util.concurrent.CompletableFuture;
6262
import java.util.concurrent.ExecutionException;
6363
import java.util.concurrent.TimeUnit;
64+
import java.util.concurrent.TimeoutException;
6465
import java.util.concurrent.atomic.AtomicInteger;
6566

6667

@@ -227,10 +228,12 @@ public Response execute(final Request request) throws IOException {
227228
throw ArangoDBException.wrap(e);
228229
} catch (ExecutionException e) {
229230
Throwable cause = e.getCause();
230-
if (cause instanceof IOException) {
231+
if (cause instanceof TimeoutException) {
232+
throw ArangoDBException.wrap(cause);
233+
} else if (cause instanceof IOException) {
231234
throw (IOException) cause;
232235
} else {
233-
throw ArangoDBException.wrap(e.getCause());
236+
throw new IOException(cause);
234237
}
235238
}
236239
checkError(resp);

resilience-tests/src/test/java/resilience/SingleServerTest.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ static void afterAll() throws IOException {
3737
}
3838

3939
@BeforeEach
40-
void beforeEach() throws IOException {
41-
endpoint.getProxy().enable();
40+
void beforeEach() {
41+
enableEndpoint();
4242
}
4343

4444
protected static Endpoint getEndpoint() {
@@ -57,4 +57,22 @@ protected static ArangoDBAsync.Builder dbBuilderAsync() {
5757
.password(PASSWORD);
5858
}
5959

60+
protected void enableEndpoint(){
61+
try {
62+
getEndpoint().getProxy().enable();
63+
Thread.sleep(100);
64+
} catch (IOException | InterruptedException e) {
65+
throw new RuntimeException(e);
66+
}
67+
}
68+
69+
protected void disableEndpoint(){
70+
try {
71+
getEndpoint().getProxy().disable();
72+
Thread.sleep(100);
73+
} catch (IOException | InterruptedException e) {
74+
throw new RuntimeException(e);
75+
}
76+
}
77+
6078
}

resilience-tests/src/test/java/resilience/connection/ConnectionTest.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.junit.jupiter.params.ParameterizedTest;
99
import org.junit.jupiter.params.provider.MethodSource;
1010

11-
import java.io.IOException;
1211
import java.net.ConnectException;
1312
import java.net.UnknownHostException;
1413
import java.util.stream.Stream;
@@ -59,21 +58,18 @@ void nameResolutionFailTest(Protocol protocol) {
5958

6059
@ParameterizedTest
6160
@MethodSource("arangoProvider")
62-
void connectionFailTest(ArangoDB arangoDB) throws IOException, InterruptedException {
63-
getEndpoint().getProxy().disable();
64-
Thread.sleep(100);
61+
void connectionFailTest(ArangoDB arangoDB) {
62+
disableEndpoint();
6563

6664
Throwable thrown = catchThrowable(arangoDB::getVersion);
6765
assertThat(thrown).isInstanceOf(ArangoDBException.class);
6866
assertThat(thrown.getMessage()).contains("Cannot contact any host");
6967
assertThat(thrown.getCause()).isNotNull();
7068
assertThat(thrown.getCause()).isInstanceOf(ArangoDBMultipleException.class);
71-
((ArangoDBMultipleException) thrown.getCause()).getExceptions().forEach(e -> {
72-
assertThat(e).isInstanceOf(ConnectException.class);
73-
});
69+
((ArangoDBMultipleException) thrown.getCause()).getExceptions().forEach(e ->
70+
assertThat(e).isInstanceOf(ConnectException.class));
7471
arangoDB.shutdown();
75-
getEndpoint().getProxy().enable();
76-
Thread.sleep(100);
72+
enableEndpoint();
7773
}
7874

7975
}

resilience-tests/src/test/java/resilience/reconnection/ReconnectionTest.java

Lines changed: 0 additions & 119 deletions
This file was deleted.

0 commit comments

Comments
 (0)